JVM class文件结构

1.字段表集合

字段表集合是指由若干个字段表(field_info)组成的集合。对于在类中定义的若干个字段,经过JVM编译成class文件后,会将相应的字段信息组织到一个叫做字段表集合的结构中,字段表集合是一个类数组结构。字段表集合位于字段计数器后面。

Class文件结构


2.方法集在class中的组织

方法表集合是指由若干个方法表(method_info)组成的集合。对于在类中定义的若干个,经过JVM编译成class文件后,会将相应的method方法信息组织到一个叫做方法表集合的结构中,字段表集合是一个类数组结构。

方法表的结构体由:访问标志(access_flags)、名称索引(name_index)、描述索引(descriptor_index)、属性表(attribute_info)集合组成。

名称索引指向了常量池中的某一个常量池项,这个方法的名称以UTF-8格式的字符串存储在这个常量池项中,是函数的名称。

描述索引表示的是这个方法的特征或者说是签名一个方法会有若干个参数和返回值,而若干个参数的数据类型和返回值的数据类型构成了这个方法的描述,其基本格式为:     (参数数据类型描述列表)返回值数据类型   。描述索引指向了常量池中的某个常量池项。

属性表集合非常重要,方法的实现被JVM编译成JVM的机器码指令机器码指令就存放在一个Code类型的属性表中;如果方法声明要抛出异常,那么异常信息会在一个Exceptions类型的属性表中予以展现。

属性表的内容包括:


  • 这个方法的代码实现,方法的可执行的机器指令
  • 这个方法声明的要抛出的异常信息
  • 这个方法是否被@deprecated注解表示
  • 这个方法是否是编译器自动生成的


一、Code类型的属性表(attribute_info)可以说是class文件中最为重要的部分,因为它包含的是JVM可以运行的机器码指令,JVM能够运行这个类,就是从这个属性中取出机器码的。除了要执行的机器码,它还包含了一些其他信息

Code属性表的组成部分:

机器指令----code:

目前的JVM使用一个字节表示机器操作码,即对JVM底层而言,它能表示的机器操作码不多于28 次方,即 256个。


异常处理跳转信息---exception_table:

如果代码中出现了try{}catch{}块,那么try{}块内的机器指令的地址范围记录下来,并且记录对应的catch{}块中的起始机器指令地址,当运行时在try块中有异常抛出的话,JVM会将catch{}块对应懂得其实机器指令地址传递给PC寄存器,从而实现指令跳转;


Java源码行号和机器指令的对应关系---LineNumberTable属性表:

编译器在将java源码编译成class文件时,会将源码中的语句行号跟编译好的机器指令关联起来,这样的class文件加载到内存中并运行时,如果抛出异常,JVM可以根据这个对应关系,抛出异常信息,告诉我们我们的源码的多少行有问题,方便我们定位问题。

默认情况下,编译器会生成这一项信息,如果你项取消这一信息,你可以使用-g:none-g:lines来取消或者要求设置这一项信息。如果使用了-g:none来生成class文件,class文件中将不会有LineNumberTable属性表,造成的影响就是 将来如果代码报错,将无法定位错误信息报错的行,并且如果想调试代码,将不能在此类中打断点(因为没有指定行号。)



局部变量表描述信息----LocalVariableTable属性表:

局部变量表信息会记录栈帧局部变量表中的变量和java源码中定义的变量之间的关系,这个信息不是运行时必须的属性,默认情况下不会生成到class文件中。你可以根据javac指令的-g:none或者-g:vars选项来取消或者设置这一项信息。

补充:

1.在class文件中,在访问标志前面的有常量池。

2.JVM为没有显式定义实例化构造方法的类,自动生成默认的实例化构造方法"<init>()。

3.java反编译

javap -v Simple > Simple.txt 查看反编译的信息

4.如果我们在类中没有定义实例化构造方法,JVM编译器在将源码编译成class文件时,会自动地为这个类添加一个不带参数的实例化构造方法,这种添加是字节码级别的,JVM对所有的类实例化构造方法名采用了相同的名称:“<init>”。如果显式地定义构造函数,那么类编译出来的class文件和不带构造方法类生成的class文件是完全相同的。这也就是为什么虽然我们显式地在类中定义类构造方法,却可以使用 new ClassName()创建实例了。


二、Exceptions类型的属性表----method方法声明的要抛出的异常信息



如果某个方法定义中,没有声明抛出异常,那么,表示该方法的方法表(method_info)结构体中的属性表集合中不会有Exceptions类型的属性表;换句话说,如果方法声明了要抛出的异常,方法表(method_info)结构体中的属性表集合中必然会有Exceptions类型的属性表,并且该属性表中的异常数量不小于1



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值