jvm学习笔记(三)类文件结构、java方法数65535上限的原因

了解class类文件结构,对于学习smali也是有必要的!

一、class类文件的结构(8位字节,一个字节占8位,以字节为基础单位的二进制流)
存储结构:class文件是一组以字节(8位)为基础单位的二进制流,各数据严格按照顺序紧凑排列在class文件中,中间没有任何分隔符。需要占用一个字节(8位)以上空间的数据,会按照高位在前的方式分割成若干个字节(8位)进行存储。
概念:无符号数和表组成。无符号数是基本数据类型,用来描述数字、索引引用、数量值、或者按照UTF-8编码构成字符串值。表是由多个无符号数或其他表作为数据项构成的符合数据类型,用来描述有层次关系的符合结构数据。
无符号类型为基本类型,以u1、u2、u4、u8表示1个字节、2个字节、4个字节、8个字节的无符号数。
1、魔数与Class文件的版本
1)class文件的头4个字节为魔数,唯一作用,确定该文件是否为一个能被虚拟机接受的class文件。【class文件类型的标识】
2)class文件的魔数值为:0xCAFEBABE
3)魔数后面的4个字节为class文件的版本号,第5、6个字节是次版本号(Minor Version),第7、8个字节为主板本号(Major Version)
2、常量池(class文件结构中与其他项目关联最多的类型、占用class文件空间最大的数据之一、class中第一个出现的表)
1)常量池入口,有一个u2类型数据表示常量池容量,常量池容量计数是从1开始的
 0用来表示某些指向常量池的索引表达不引用任何一个常量池项目,把索引值设置为0
2)常量池存放两大类常量:字面量、符号引用。
 字面量:文本字符串、声明为final的常量值
 符号引用:属于编译原理的概念
    a:类和接口的全限定名   b:字段的名称和描述符   c:方法的名称和描述符
虚拟机运行时,需要从常量池获取对应的符号引用,再在类创建时或运行时解析、翻译到具体内存地址中。

3)常量池的项目类型中有一项为 CONSTANT_Utf8_info表示UTF-8编码的字符串;

                    CONSTANT_Utf8_info的结构如下:
                       类型        名称 数量
                        u1          tag           1
                        u2          length           1
                        u1   bytes          length

 class文件中方法、字段等都需要引用CONSTANT_Utf8_info型常量来描述名称,所以CONSTANT_Utf8_info型常量的最大长度即u2类型能表达的最大值,也是Java中方法、字段名的最大长度。
u2类型,表示2个字节,16位,能表示的最大值为 2的16次方,也就是65536,而常量池容量计数是从1开始的,所以u2类型最多能表示65535个不同的值
所以Java程序中如果定义了超过64KB英文字符的变量或方法名,将无法编译。

3、访问标志
常量池后面两个字节表示访问标志,用于识别一些类、接口层次的访问信息。
包括:class是类还是接口、是否定义为public类型、是否为abstract类型、如果是类的话是否声明为final。
4、类索引、父类索引与接口索引集合
1)类索引、父类索引与接口索引集合都按顺序排列在访问标志之后
2)类索引、父类索引都是u2类型(2个字节类型)的数据,接口索引集合是一组u2类型的数据集合。
3)类索引用于确定类的全限定名
4)父类索引用于确定类的父类的全限定名
5)class文件中由这三项数据来确定这个类的继承关系。

5、字段表集合
1)字段表:用于描述接口/类中声明的变量。字段包括类级变量、实例级变量,不包括方法内部声明的局部变量。
6、方法表集合

7、属性表集合

猜你喜欢

转载自blog.csdn.net/u010577768/article/details/80292857