类文件结构
1.魔数
2.大小版本号
3.常量池大小
4.常量池
5.访问标志
常量池之后,是2个字节来表示访问标志,用于识别一些类或者接口层次的访问信息。
标志名称 标志值 含义
ACC_PUBLIC
0x0001
是否为public类型
ACC_FINAL
0x0010
是否被声明为final,只有类可以设置
ACC_SUPER
0x0020
JDK1.0.2以后这个标志都为真
ACC_INTERFACE
0x0200
标识这是一个接口
ACC_ABSTRACT
0x0400
是否为abstract类型,对于接口或抽象类来说,此标志值为真,其他类值为假
ACC_SYNTHETIC
0x1000
标识这个类并非由用户代码产生
ACC_ANNOTATION
0x2000
标识这是一个注解
ACC_ENUM
0x4000
类索引
下面case 访问标志后的2个字节000b = 11,指向常量池里的第11个常量,接下来的000c = 12,指向常量池里的第12个常量(该类的父类是Object)
父类索引
接下来的000c = 12,指向常量池里的第12个常量(该类的父类是Object)
接口索引
在本例子中,只有一个接口,0x000d十进制就是13,指向常量池中第13个常量,表示接口信息。
字段表
接口索引后面紧跟着的是字段表信息,字段表的入口前2个字节表示字段的个数,在本例子中只定义了个一个字段,所以其值为0x0001,后面紧跟着的是该字段的描述表。字段信息结构表如下:
方法表
属性表
case:
//实现类
public class BMWCar implements Car{
private String name;
public BMWCar() {
name = "宝马";
}
@Override
public void drive() {
System.out.println("BMW car drive." + name);
}
}
Last modified 2017-11-10; size 644 bytes
MD5 checksum ac6d7477d45479490e4ea3f660b1dcdd
Compiled from "BMWCar.java"
public class BMWCar implements Car
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #12.#23 // java/lang/Object."<init>":()V
#2 = String #24 // 宝马
#3 = Fieldref #11.#25 // BMWCar.name:Ljava/lang/String;
#4 = Fieldref #26.#27 // java/lang/System.out:Ljava/io/PrintStream;
#5 = Class #28 // java/lang/StringBuilder
#6 = Methodref #5.#23 // java/lang/StringBuilder."<init>":()V
#7 = String #29 // BMW car drive.
#8 = Methodref #5.#30 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#9 = Methodref #5.#31 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#10 = Methodref #32.#33 // java/io/PrintStream.println:(Ljava/lang/String;)V
#11 = Class #34 // BMWCar
#12 = Class #35 // java/lang/Object
#13 = Class #36 // Car
#14 = Utf8 name
#15 = Utf8 Ljava/lang/String;
#16 = Utf8 <init>
#17 = Utf8 ()V
#18 = Utf8 Code
#19 = Utf8 LineNumberTable
#20 = Utf8 drive
#21 = Utf8 SourceFile
#22 = Utf8 BMWCar.java
#23 = NameAndType #16:#17 // "<init>":()V
#24 = Utf8 宝马
#25 = NameAndType #14:#15 // name:Ljava/lang/String;
#26 = Class #37 // java/lang/System
#27 = NameAndType #38:#39 // out:Ljava/io/PrintStream;
#28 = Utf8 java/lang/StringBuilder
#29 = Utf8 BMW car drive.
#30 = NameAndType #40:#41 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#31 = NameAndType #42:#43 // toString:()Ljava/lang/String;
#32 = Class #44 // java/io/PrintStream
#33 = NameAndType #45:#46 // println:(Ljava/lang/String;)V
#34 = Utf8 BMWCar
#35 = Utf8 java/lang/Object
#36 = Utf8 Car
#37 = Utf8 java/lang/System
#38 = Utf8 out
#39 = Utf8 Ljava/io/PrintStream;
#40 = Utf8 append
#41 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#42 = Utf8 toString
#43 = Utf8 ()Ljava/lang/String;
#44 = Utf8 java/io/PrintStream
#45 = Utf8 println
#46 = Utf8 (Ljava/lang/String;)V
{
public BMWCar();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2 // String 宝马
7: putfield #3 // Field name:Ljava/lang/String;
10: return
LineNumberTable:
line 6: 0
line 7: 4
line 8: 10
public void drive();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #5 // class java/lang/StringBuilder
6: dup
7: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
10: ldc #7 // String BMW car drive.
12: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_0
16: getfield #3 // Field name:Ljava/lang/String;
19: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
25: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
28: return
LineNumberTable:
line 12: 0
line 13: 28
}
SourceFile: "BMWCar.java"
class指令:
getStatic 获得静态资源(有待考究)
new 对应java New
invokespecial 调用static方法
ldc 入栈
invokevirtual 调用普通方法