1、Javap命令工具
1)javap命令工具:可以查看编译后的指令
2)const #1 = Method #6.#21 // java/lang/object.”<init>”:()V 代表意思:java.lang.Object类的构造方法,入口参数个数为0,返回值为void。
3)<init>:构造方式,V代表返回值为void
4)const #3 Field #23.#24 // java/lang/System.out:Ljava/io/PrintStream; Field代表一个属性 完整含义:获取到java/lang/System类的属性out,out的类型是Ljava/io/PrintStream
5)const #4 = Method #23.#26 // java/io/PrintSteam.Println(Z)V 其中Method 代表一个方法,Z代表boolean类型 完整含义:调用java/io/PrintStream类的println方法,方法的范湖值类型是void,入口类型是boolen
6)const #24 = NameAndType #32.#33 其中NameAndType 代表名称和类型
7)Stack = 1,Locals = 1,Args_size=1 含义: Stack代表栈顶的单位大小 Locals 是本地变量的slot个数 Args_size 代表是入口参数的个数
8)0:aload_0 代表含义:第一个0代表虚指令中的行号,aload_0 代表是将第1个slot所在在本地变量推到栈顶,且该本地变量是引用类型的
9)astore_0:将栈顶的引用值写入第一个slot本地变量中
10)c = 1 c = c++ 最后输入c,结果是1不是2,原因是: JVM首先将int类型的常量1推到栈顶,将栈顶的数据赋值给第一个slot所在的int类型的本地变量中,其次将第一个slot所在int类型的本地变量放入栈顶,将本地变量加1,最后将栈顶的数据赋值给第一个slot所在的int类型的本地变量中。所以c++根本没参与其中的计算,只是自己在加,没有赋值
11)指令iconst_1 :将int 类型的常量1推送到栈顶 istore_0 : 将栈顶数据抛出赋值给第一个slot所在的int类型的本地变量中 iinc 0 :将第一个slot所在的int类型的本地变量自加1 iload_0 :将第1个slot所在的int类型的本地变量加载到栈顶
2、Java字节码结构
1)Java语言是一种跨平台语音,原因是Java的Class文件是统一的,给予字节码的,而字节码是以byte为单位储存的,JVM将其翻译成对应的OS指令
2)Java字节码文件的主体结构:由上而下依次是Class文件头部、常量池区域、当前类的一些描述信息、属性列表、方法列表、attibute列表
3)Class头部机构:由上而下依次是4个字节头部验证码、minor version、major version
4)类的基本描述信息结构:由上而下依次是Class的入口修饰符、常量池入口指向类名、常量池入口指向父类、接口数量、常量池入口(接口1、2等等)。。。