(十五)类索引
一、概念
上一章节讲到了访问标志,如下表可知访问标志之后是this_class(这个类)和super_class(父类)和interfaces_count(继承接口的数量)和interfaces(继承的接口),各占2个字节。
类型 | 名称 | 数量 |
u4 | magic | 1 |
u2 | minor_version | 1 |
u2 | major_version | 1 |
u2 | constant_pool_count | 1 |
cp_info | constant_pool | constant_pool_count - 1 |
u2 | access_flags | 1 |
u2 | this_class | 1 |
u2 | super_class | 1 |
u2 | interfaces_count | 1 |
u2 | interfaces | interfaces_count |
u2 | fields_count | 1 |
field_info | fields | fields_count |
u2 | methods_count | 1 |
method_info | methods | methods_count |
u2 | attribute_count | 1 |
attribute_info | attributes | attributes_count |
二、例子
- 编写一个类,继承一个类,并实现了多个接口,如下
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; public class Test extends FileInputStream implements Runnable,ActionListener{ public Test(File file) throws FileNotFoundException { super(file); // TODO Auto-generated constructor stub } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub } @Override public void run() { // TODO Auto-generated method stub } }
- 用javac编译后,打开class文件,如下图
- 用javap 命令行查看如下代码
- ,thisc_class在常量池中的位置是0x0002 = 2 ,对比下面金色部分#2代表的是Test,所以this_class的值为Test,即本类是Test类。
- super_class在常量池中的位置是0x0002 = 3,对比下面金色部分#3代表的是java/io/FileInputStream
,所以super_class的值为java/io/FileInputStream,即父类是FileInputStream类。 - 接口的数量为:0x0002 = 2 ,表示有两个接口
- 两个接口的位置跟this_class和super_class一样,不再解释。
C:\Users\Administrator\Desktop>javap -verbose Test.class Classfile /C:/Users/Administrator/Desktop/Test.class Last modified 2018-5-13; size 471 bytes MD5 checksum 150d8c5a88b79752ec7a2200bff2b737 Compiled from "Test.java" public class Test extends java.io.FileInputStream implements java.lang.Runnable,java.awt.event.ActionListener minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #3.#18 // java/io/FileInputStream."<init>":(Ljava/io/File;)V #2 = Class #19 // Test #3 = Class #20 // java/io/FileInputStream #4 = Class #21 // java/lang/Runnable #5 = Class #22 // java/awt/event/ActionListener #6 = Utf8 <init> #7 = Utf8 (Ljava/io/File;)V #8 = Utf8 Code #9 = Utf8 LineNumberTable #10 = Utf8 Exceptions #11 = Class #23 // java/io/FileNotFoundException #12 = Utf8 actionPerformed #13 = Utf8 (Ljava/awt/event/ActionEvent;)V #14 = Utf8 run #15 = Utf8 ()V #16 = Utf8 SourceFile #17 = Utf8 Test.java #18 = NameAndType #6:#7 // "<init>":(Ljava/io/File;)V #19 = Utf8 Test #20 = Utf8 java/io/FileInputStream #21 = Utf8 java/lang/Runnable #22 = Utf8 java/awt/event/ActionListener #23 = Utf8 java/io/FileNotFoundException { public Test(java.io.File) throws java.io.FileNotFoundException; descriptor: (Ljava/io/File;)V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: invokespecial #1 // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V 5: return LineNumberTable: line 10: 0 line 12: 5 Exceptions: throws java.io.FileNotFoundException public void actionPerformed(java.awt.event.ActionEvent); descriptor: (Ljava/awt/event/ActionEvent;)V flags: ACC_PUBLIC Code: stack=0, locals=2, args_size=2 0: return LineNumberTable: line 18: 0 public void run(); descriptor: ()V flags: ACC_PUBLIC Code: stack=0, locals=1, args_size=1 0: return LineNumberTable: line 24: 0 } SourceFile: "Test.java"