Java类文件结构详解

8 篇文章 0 订阅

类文件结构

package com.szu.jvm.learn01_bytecode;
/*
 * @Author 郭学胤
 * @University 深圳大学
 * @Description
 * @Date 2021/2/20 13:33
 */
public class L01_EmptyClass {
}

下图为一个空文件编译出来的class文件

在这里插入图片描述

1. 魔数和version

  • 前四个字节:CA FE BA BE,类文件固定开头,名字叫做魔数(magic number)

  • 第五六七八字节:00 00 00 3B,代表版本信息, 其中前两个字节为minor version,后两个字节为major version

    JDK15编译出来为 3B, JDK11编译出来为37

在这里插入图片描述

2. 常量池(表格在最后)

往后开始常量池部分,这是类文件中最常的部分之一。常量池中的部分基本都是互相引用,所以查看起来比较复杂。

常量池最开始的两个字节代表常量池中常量数量,十六进制0x10 = 16常量的数量为16 - 1 = 15项

第一项

(查表可知,表在最后)

0A 代表 Method_ref_info,后边是两个两个字节的数:00 03 00 0D

所以00 03指向的常量池中的第三项,所以第三项就是这个方法的类型描述符

00 0D指向的是常量池中的第十三项,第十三项就是这个方法的名字和返回值类型

在这里插入图片描述

第二项

在这里插入图片描述

07:代表 Class_info

00 0E 指向常量池的第14项,意思就是第14项存储的字符串就是这个类的全限定名

第三项

在这里插入图片描述

07:代表 Class_info

00 0F 指向常量池的第15项,意思就是第15项存储的字符串就是这个类的全限定名

常量池的第一项的第一个参数指向第三项,第三项又指向第十五项,所以第十五项是什么,第一项那个方法的类型描述符是什么了。

在这里插入图片描述

直接看第十四和十五项,

查表可知这两项都是字符串

红框01代表后边是 UTF8字符串,后边的绿框代表这个字符串的长度,00 2B = 4300 10 = 16

第14项为第一个字符串:com/szu/jvm/learn01_bytecode/L01_EmptyClass

  • 因为第二项指向第14项,所以此类全限定名为com/szu/jvm/learn01_bytecode/L01_EmptyClass

第15项为第二个字符串为java/lang/Object

  • 此类第一项那个方法的类型为java/lang/Object类型,虽然是一个空类,但是每个类都有自己的默认构造方法,然而每个类都是Object的子类,所以会有这种现象存在。

3. 访问标志

在这里插入图片描述

在这里插入图片描述

00 21代表此类是一个public的类

如果是public interface的话,那么这两个字节会变成 02 01,0200代表是个接口,0001代表public,两个值进行与运算

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

在这里插入图片描述

第一个为本类索引,指向常量池中第二项,常量池第二项指向第十四项com/szu/jvm/learn01_bytecode/L01_EmptyClass

第二个为父类索引,指向常量池第三项,第三项指向第十五项java/lang/Object

接口可以有多个,但是本类中暂时没写任何实现接口,所以此处为0

5.字段表集合

用于描述类中声明的变量,Java语言中的“字段”(Field)包括类级变 量以及实例级变量,但不包括在方法内部声明的局部变量

字段可以包括的修饰符有字段的作用域(public、private、protected修饰 符)、是实例变量还是类变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否 强制从主内存读写)、可否被序列化(transient修饰符)、字段数据类型(基本类型、对象、数组)、 字段名称。

此时我们使用下边的代码来看类文件

package com.szu.jvm.learn01_bytecode;
/*
 * @Author 郭学胤
 * @University 深圳大学
 * @Description
 * @Date 2021/2/20 13:33
 */

public class L01_EmptyClass {

    private int m;
}

在这里插入图片描述

00 01代表字段表长度

00 02 access_flags,访问修饰符(见下表)

00 04 表示字段名称,指向常量池中的元素

00 05 代表字段类型,指向常量池中的元素

在这里插入图片描述

6.方发表集合

public class L01_EmptyClass {

    private int m;

}

在这里插入图片描述

00 01代表方法数量(此时只有一个默认的构造方法)

00 01,access_flags

00 06,方法名称,指向常量池的6号元素,构造方法用<init>表示

00 07,方法的描述符,也就是返回值类型,void用<()V>表示

00 01 参数数量

00 08参数的名称,指向常量池中的元素

7.属性表集合

7.1 code属性 + 异常表

方法体里面的代码经过编译器处理之后,最终变为字节码指令存储在Code属性内。

code属性中有

  • 局部变量表所需的存储空间
  • 操作数栈深度的最大值。
  • code_length和code用来存储编译后生成的字节码指令,一个方法不允许超过65535条字节码指令
    • 异常表
public int inc() {
    int x;
    try {
        x = 1;
        return x;
    } catch (Exception e) {
        x = 2;
        return x;
    } finally {
        x = 3;
    }
}

// 编译后的ByteCode字节码及异常表

public int inc();
    Code:
        Stack=1, Locals=5, Args_size=1
        0: iconst_1 // try块中的x=1
        1: istore_1
        2: iload_1 // 保存x到returnValue中,此时x=1
        3: istore 4
        5: iconst_3 // finaly块中的x=3
        6: istore_1
        7: iload 4 // 将returnValue中的值放到栈顶,准备给ireturn返回
        9: ireturn
        10: astore_2 // 给catch中定义的Exception e赋值,存储在变量槽 2中
        11: iconst_2 // catch块中的x=2
        12: istore_1
        13: iload_1 // 保存x到returnValue中,此时x=2
        14: istore 4
        16: iconst_3 // finaly块中的x=3
        17: istore_1
        18: iload 4 // 将returnValue中的值放到栈顶,准备给ireturn返回
        20: ireturn
        21: astore_3 // 如果出现了不属于java.lang.Exception及其子类的异常才会走到这里
        22: iconst_3 // finaly块中的x=3
        23: istore_1
        24: aload_3 // 将异常放置到栈顶,并抛出
        25: athrow
            
    Exception table:
    from 	to 		target 		type
    0 		5 		10 			Class java/lang/Exception
    0 		5 		21		 	any
    10 		16		21 			any

7.2 Exceptions属性

属性的作用是列举出方法中可能抛出的受查异常,不要与前面刚刚讲解完的异 常表产生混淆。

7.3 LineNumberTable属性

用于描述Java源码行号与字节码行号(字节码的偏移量)之间的对应关系。 它并不是运行时必需的属性,但默认会生成到Class文件之中。

7.4 其他

  • InnerClasses属性

  • Signature属性

  • 等等吧

常量池内容表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值