Java .class文件结构总结

参考《深入理解Java虚拟机:第3版》第6章

0.概览

一个单元格表示u1大小(1byte)
.class 文件结构

1.魔数与版本号

0xCAFEBABE

u4大小

MinorVersion

次版本号,u2大小

TargetVersion

主版本号,u2大小


2.常量池表

内容

  • 字面量:文本字符串、被声明为final的常量
  • 符号引用:类、接口的全限定名,字段和方法的简单名称和标识符等

结构

开头以一个u2大小的constant_pool_count开始,后面紧接constant_pool_count个常量,索引从1开始,而不是0

17种数据类型以及结构

P222 表6-6


3.类访问标志

标志类或者接口的访问信息


4.类索引、父类索引、接口索引

这些索引用于确定对应的类或者接口的全限定名java/lang/Object)


5.字段表

几个概念词

  • 字段或方法的简单名称:比如方法inc()和字段m的简单名称分别是inc,m
  • 字段数据类型、方法的参数列表和返回值的描述符:一维数组[, 对象Ljava/lang/String等等
  • 类的全限定名:包含整个包路径的名称 java/lang/String

内容

  • 类级变量:static, static final修饰的变量
  • 实例级变量

6.方法表

方法表的结构和字段表差不多,略

重载在方法表中的体现

  1. 两个方法的简单名称相同
  2. 两个方法的特征签名不同
    特征签名:方法中各个参数对前面常量池表中的引用的集合

但是,.Class文件结构合法性只要求两个方法的描述符不一样即合法


7.属性表

属性表被附加在之前的方法表、字段表、或者一个属性表后面,
总结下Code属性表,其他的略了,太多了

Code属性表

表结构

见书上

一个方法后面的Code属性实例

附加在方法表的后面,主要是我们写的真正的逻辑代码,这里面的代码是javac编译器编译成的字节码指令

比如下面这段代码表示的方法

private int test(int a, int b) {
    
    
        return a + b;
}

.class文件中,Code属性被放在了方法信息后面,作为附属属性
Code属性后面还可以附加属性表,这里是

  • LineNumerTable表示这个方法开始的代码对应源代码的哪一行
  • LocalVariableTable就是局部变量表,里面有一个this也就是这个对象的引用,也就是我们经常用的那个

Code: stack 表示这个方法的最大操作栈深度
Code: locals 表示这个方法的所需的最大局部变量数
Code: args_size 表示这个方法的参数个数

  private int test(int, int);
    descriptor: (II)I //描述符
    flags: (0x0002) ACC_PRIVATE // 标示
    Code: // Code属性从这里开始
      stack=2, locals=3, args_size=30: iload_1
         1: iload_2/
         3: ireturn/
      LineNumberTable: // Code属性的附属属性
        line 13: 0
      LocalVariableTable: // Code属性的附属属性
        Start  Length  Slot  Name   Signature
            0       4     0  this   LDemo;
            0       4     1     a   I
            0       4     2     b   I

其他属性表

见书上

猜你喜欢

转载自blog.csdn.net/qq_43709922/article/details/112069993