字节码层面分析class文件

2021-10-05  本文已影响0人  HardMan

class的来龙去脉

Java提供了一种可以在所有平台上都能使用的一种中间代码--字节码类文件(class文件)

class的组成

从纵观的角度看,class文件里只有两种数据结构:无符号数和表

无符号数和表组成了class的各个结构,这些结构按照预先规定好的顺序紧密的从前向后排列,相邻的项之间没有任何间隙

class文件结构

实例分析

源码 字节码

魔数(magic number)
在class文件开头的四个字节是class文件的魔数,它是一个固定值--0xcafebabe ,魔数是class文件的标志,它是判断一个文件是不是class文件的标准。
版本号
紧跟在魔数后面的四个字节是版本号,前面两个字节代表次版本号,后两个字节代表主版本号。
常量池表(cp_info)
在常量池中保存了类的各种相关信息,比如类的名称、父类的名称、类中的方法名、参数名称、参数类型。
常量池的组织很简单,前端两个字节占有的位置叫做常量池计数器,它记录着常量池的组成元素(常量池项 cp _info)的个数。

每个常量池项都会对应记录着class文件中的某种类型的字面量。JVM根据常量池项中的tag来确定这个常量池项表示的是哪种类型的字面量。



注意 常量池中保存的主要是字面量和符号引用。
字面量是由字命、数字等构成的字符串或数值,字面值只以右值出现。比如 int a=10;string str=”hello“,其中的10 和”hello“都是字面量。
符号引用:符号引用是编译原理中的概念,是相对于直接引用来说的。主要包括了以下三类常量: * 类和接口的全限定名 * 字段的名称和描述符 * 方法的名称和描述符


package com.louis.jvm;
 
public class StringTest {
    private String s1 = "JVM原理";
    private String s2 = "JVM原理";
    private String s3 = "JVM原理";
    private String s4 = "JVM原理";
}


结合上图,#15的常量池项的tag=8,对应表示java.lang.string 的对象,查看表结构,结构体存放的是对#16常量项的指向,而#16存放的是真正的字符串内容。

访问标志(access flag)

紧跟在常量池之后的常量是访问标志,占用两个字节。代表着类或者接口,是否被定义成public,是否是abstract,如果是类,是否被声明成final。


类索引、父类索引、接口索引计数器

标志后2个字节就是类索引,类索引后两个字节是父类索引,父类索引后两个字节是接口索引计数器。
索引都是指向常量池的第某个常量。

字段表

字段表的主要功能是用来描述类或者接口中声明的变量。这里的字段包含类级别变量以及实例变量,不包括方法内部声明的局部变量。组成结构:字段计数器,字段访问标志,变量名索引,变量类型索引。

方法表

方法表主要描述类中的方法。也是以一个计数器开始的

上一篇 下一篇

猜你喜欢

热点阅读