Java-字节码文件深入解析的学习

JAVA字节码整体结构

class文件结构中常量池中11种数据类型结构表

 

Access_Flag访问标志

 

字段表集合

fields_count:u2

 

方法表

methods_count:u2

 

方法的属性结构

方法中的每一个属性都是一个attribute_info:

1.使用javap -verbose分析一个字节码文件时,将会分析该字节码的魔数、版本号、常量池、类信息、类的构造方法、类中的方法信息、类变量与成员变量信息。

2.所有的.class文件的前四个字节都是魔数,魔数值为固定值0xCOFEBABE。

3.魔数之后的四个字节为版本信息,前两个字节为minor version(次版本号)后两个字节为major version(主版本号)

比如00 00 00 34换算为十进制即为0为次版本号,3*16+4=52为主版本号(52对应为jdk8、51位jdk7.。。,),所以版本号即为

1.8.0。

4.常量池(constant pool):紧接着主版本字节码之后便是常量池入口,一个类中定义的很多信息都是又由常量池来维护和描述的,可以将常量池看作为Class文件的资源库,比如Java中的方法和变量信息,都是存储在常量池中的,常量池中主要存储两类常量:字面量和符号引用。字面量如文本字符串,Java中声明为final类型的常量等,而符号引用如类和接口的全局限定名,字段的名称和描述符,方法的名称和描述符。、

5.常量池总体结构:Java类对应的常量池主要由常量池数量和常量池数组(常量表)组成,常量池数量紧跟在主版本后面,占据两个字节;常量池数组则跟在常量池数量后面,常量池数组与一般的数组不同的是,常量池数组中不同元素的类型、结构都是不同的,长度当然也就不同,但是每一种元素的第一个数据都是一个u1类型,该类型是个标志位,占据一个字节,JVM在解析的时候会根据ul的类型去获取元素的具体类型。注意:常量池数组中元素的个数 = 常量池数 - 1(其中0暂时不使用)。目的是在于某些常量池索引值的数据在特定的情况下需要表达【不引用任何一个常量池】的含义;根本原因在于索引为0也是一个常量(保留常量),只不过它不位于常量表中,这个常量就对应null值;所以常量池的索引是从1开始而不是0。

6.在JVM规范中,每个变量\字段都有描述信息,描述信息主要的作用是描述字段的数据类型、方法的参数列表(包括数量、类型与顺序)与返回值,无返回值和基本数据类型都有一个大写字母表示,对象类型则是由L加上类的全限定名表示,为了压缩体积基本数据类型都由一个大写字母表示:int-I、char-C等,对象类型例:String类型对象为Ljava/lang/String;

7.对于数组类型来说每一个维度使用前置的[来表示,int[]为[I

8.用描述符描述方法时,先按照参数列表,将参数列表按照顺序放到()中然后返回值如:String getName(int age,String card)表示为(I,Ljava/lang/String)Ljava/lang/String

 

说明:

对于Java类中的每一个实例方法(非static方法),其在编译后所生成的字节码当中,方法参数的数量总是会比源代码中方法参数多一个(this),它位于方法的第一个参数位置处;这样我们就可以在方法中用this去访问当前对象的属性和其他方法。

这个操作是在编译期间完成,即由javac在编译的时候将对this的访问转化为对一个普通方法的参数访问;接下来在运行期间,由JVM调用方法时传入该this参数,所以在实例方法中至少存在一个变量this指向当前的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值