类文件结构(jvm6章)

16进制文件 下列的数字代表字节数    索引中存放的是常量池中第几个常量的引用(常量池计数器从1开始 1代表存在0个常量)

class文件中方法的返回值也作为特征签名即可同时存在一个class文件中      重载

特征签名 (class)返回值 方法名 参数列表

特征签名 (类) 方法名 参数列表   

字段表结构【2(访问权限标记符)+2(名字索引)+2(描述标识字符)+2(属性计数器)+ attribute_info(属性)】
attribute_info(属性) 基本结构  其它按需增加
2(属性名attribute_name_index)+4(长度attribute_length)+1(信息info)
描述标识字符B byte C char D double F float I int J long S short Z boolean V void L 对象类型 如Ljava/lang/Object int indexOf(char[] s,int a,int b,char[] ss,int x,int y,int z)描述符为([CIICIII)I           
(访问权限标记符)         
ACC_PUBLIC 0X0001   ACC_PRIVATE 0X0002    ACC_PROTECT 0X0004  ACC_STATIC 0X0008  
   ACC_FINAL 0X0010 ACC_VOLATILE 0X0040 ACC_TRANSIENT 0X0080  
        
 ACC_SYNTHETIC 0X1000    ACC_ENUM 0X4000
方法表结构【2(访问权限标记符)+2(名字索引)+2(描述标识字符)+2(属性计数器)+attribute_info(属性)】
ACC_PUBLIC 0X0001   ACC_PRIVATE 0X0002    ACC_PROTECT 0X0004  ACC_STATIC 0X0008  
ACC_FINAL 0X0010 ACC_SYNCHRONIZED 0x0020  ACC_BRIGGE 0X0040 是否由编译器产生的桥接方法 ACC_VARARGS 0X0080 接受不定参 
ACC_NATIVE 0x0100  ACC_ABSTRACT 0x0400 ACC_STRICTFP 0x0800 是否为strictfp    
 ACC_SYNTHETIC 0X1000    

                   类的访问权限标志
ACC_PUBLIC 0X0001 是否public   
ACC_FINAL 0x0010    ACC_SUPER 0X0020 jdk以后1.0默认真
ACC_INTERFACE 0X0200     ACC_ABSTRACT 0X0400
ACC_SYNTHETIC 0X1000标识类并非由用户代码产生 ACC_ANNOTATION 0X2000标识为注解 ACC_ENUM 0X4000


                                                                      常量池                               

4(魔数cafebaby)+4(版本号 2次+2主)+【2(常量池常量个数)+一系列表(14种,见下图)】+2(类的访问权限标志)+2(类索

                                 接口集合                                            字段表集合

引)+2(父类索引)+【2(接口计数器)+一系列接口索引()】 +【2(字段计数器,标记字段个数)+一系列字段表结构】+

         方法表集合(方法的java代码存放在Code属性里面)

【2(方法计数器)+一系列方法】 +【2 attribute_count+attribute_info】







              
              
              
              




              
 Attribute_info      

1.Code属性 方法参数值从1开始



显式异常处理表【2 (start_pc)+2(end_pa)+2(handler_pc)+2(catch_type)】

字节码在spc行到epc行出现了catch_type(指向一个class_info型常量索引)或者其它子类的异常,则转到h_pc继续执行,当c_t为0时,代表任意异常情况都需要转向h_pc进行处理.

2.Exception属性

      与code平级  作用是列举方法中可能抛出的受查异常  throws关键字后的列举的异常

                                 number_of_exception                                     exception_index_table

2(属性名)+4(属性长)+2(可能抛出多少种异常,即多少个异常表)+2(一个异常表,包含一个class_info索引,异常类型)...



3.LineNumberTable属性

用于描述java源码行号与字节码行号之间的对应关系 非必须,异常时 是否显示堆栈出错行号 默认开                     

                  

2(name)+4(length)+2(line_number_table_length)+line_number_table(数量为line_number_table_length,类型为line_number_info的集合)

              
line_number_info   包括  2(start_pc  字节码行号)+2(line_number    java源代码行号)   
              



4.LocalVariableTable属性

描述栈帧中局部变量表中的变量与java源代码中定义的变量之间的关系 非必须 关闭以后其他人引用该方法的时候,所有的参数名称丢失,ide会用arg0,arg1.....参数代替而且调试期间无法根据参数名称从上下文获得参数值

2(name)+4(count)+2(local_variable__table_length)+local_variable_info(数量为local_variable__table_length,类型为local_variable__info的集合)

                  局部变量生命周期开始的字节码偏移量以及作用范围覆盖的长度

local_variable__info 包括 2(start_pc)+2(length)+2(name_index)+2(decription_index)+2(index)

                                                   局部变量名+描述符             栈帧局部变量表中Slot的位置

                                                                               当为double long时 占用index index+1



 
5.SourceFile属性.

用于记录生成这个Class文件的源文件名称,可选非必须

2(attribute_name_index)+4(attribute_length)+2(sourcefile_index指向常量池中CONSTANT_info型常量的索引,即文件名)

6. ConstantValue属性

通知虚拟机自动为静态变量赋值,只有被static关键字修饰的变量才可以拥有该属性

 

 

 

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

magic
魔数,魔数的唯一作用是确定这个文件是否为一个能被虚拟机所接受的 Class 文件。魔
数值固定为 0xCAFEBABE,不会改变

minor_version、major_version
副版本号和主版本号

constant_pool_count
常量池计数器,constant_pool_count的值等于constant_pool表中的成员数加1。
constant_pool 表的索引值只有在大于 0 且小于 constant_pool_count 时才会被
认为是有效的,对于 long 和 double 类型有例外情况,可参见§4.4.5。


constant_pool[]
常量池,constant_pool 是一种表结构(§4.4),它包含 Class 文件结构及其子结构
中引用的所有字符串常量、类或接口名、字段名和其它常量。常量池中的每一项都具备相
同的格式特征——第一个字节作为类型标记用于识别该项是哪种类型的常量,称为“tag
byte”。常量池的索引范围是 1 至 constant_pool_count−1

access_flags
访问标志,access_flags 是一种掩码标志,用于表示某个类或者接口的访问权限及基
础属性


ACC_PUBLIC  0x0001  可以被包的类外访问。
ACC_FINAL  0x0010  不允许有子类。
ACC_SUPER  0x0020
当用到 invokespecial 指令时,需要特殊处理 ③ 的
父类方法。
ACC_INTERFACE  0x0200  标识定义的是接口而不是类。
ACC_ABSTRACT  0x0400  不能被实例化。
ACC_SYNTHETIC  0x1000  标识并非 Java 源码生成的代码
ACC_ANNOTATION  0x2000  标识注解类型
ACC_ENUM  0x4000  标识枚举类型
    带有 ACC_SYNTHETIC 标志的类,意味着它是由编译器自己产生的而不是由程序员
编写的源代码生成的。
    带有 ACC_ENUM 标志的类,意味着它或它的父类被声明为枚举类型。
    带有 ACC_INTERFACE 标志的类,意味着它是接口而不是类,反之是类而不是接口。
如果一个 Class 文件被设置了 ACC_INTERFACE 标志,那么同时也得设置ACC_ABSTRACT 标志
。同时它不能再设置 ACC_FINAL、ACC_SUPER 和 ACC_ENUM 标志。
    注解类型必定带有 ACC_ANNOTATION 标记,如果设置了 ANNOTATION 标记ACC_INTERFACE
也必须被同时设置 如果没有同时设置 ACC_INTERFACE 标记,那么这个Class文件可以具有表
中的除ACC_ANNOTATION外的所有其它标记。当然 ACC_FINAL 和 ACC_ABSTRACT 这类互斥的标记除外
    ACC_SUPER 标志用于确定该 Class 文件里面的 invokespecial 指令使用的是哪一种执行语义
目前 Java 虚拟机的编译器都应当设置这个标志。ACC_SUPER 标记是为了向后兼容旧编译器编译的
Class 文件而存在的
     access_flags 标志位是为未来扩充而预留的,编译器中会被设置为 0, Java 虚拟机实现也会
自动忽略它们


this_class
类索引,this_class 的值必须是对 constant_pool 表中项目的一个有效索引值。
constant_pool 表在这个索引处的项必须为 CONSTANT_Class_info 类型常量
,表示这个 Class 文件所定义的类或接口


super_class
父类索引,对于类来说,super_class 的值必须为 0 或者是对 constant_pool 表中
项目的一个有效索引值。如果它的值不为 0,那 constant_pool 表在这个索引处的项
必须为 CONSTANT_Class_info 类型常量(§4.4.1),表示这个 Class 文件所定义的
类的直接父类。当前类的直接父类,以及它所有间接父类的 access_flag 中都不能带
有 ACC_FINAL 标记。对于接口来说,它的 Class 文件的 super_class 项的值必须是
对 constant_pool 表中项目的一个有效索引值。constant_pool 表在这个索引处的
项必须为代表 java.lang.Object 的 CONSTANT_Class_info 类型常量。
如果 Class 文件的 super_class 的值为 0,那这个 Class 文件只可能是定义的是
java.lang.Object 类,只有它是唯一没有父类的类。


interfaces_count
接口计数器


interfaces[]
接口表,interfaces[]数组中的每个成员的值必须是一个对 constant_pool 表中项
目的一个有效索引值,它的长度为 interfaces_count。每个成员 interfaces[i] 必
须为 CONSTANT_Class_info 类型常量(§4.4.1),其中 0 ≤ i <
interfaces_count。在 interfaces[]数组中,成员所表示的接口顺序和对应的源
代码中给定的接口顺序(从左至右)一样,即 interfaces[0]对应的是源代码中最左
边的接口


fields_count
字段计数器,fields_count 的值表示当前 Class 文件 fields[]数组的成员个数。
fields[]数组中每一项都是一个 field_info 结构的数据项,它用于表示
该类或接口声明的类字段或者实例字段


fields[]
字段表,fields[]数组中的每个成员都必须是一个 fields_info 结构(§4.5)的数
据项,用于表示当前类或接口中某个字段的完整描述。fields[]数组描述当前类或接口
声明的所有字段,但不包括从父类或父接口继承的部分


methods_count
方法计数器,methods_count 的值表示当前 Class 文件 methods[]数组的成员个数。
Methods[]数组中每一项都是一个 method_info 结构


methods[]
方法表,methods[]数组中的每个成员都必须是一个 method_info 结构的
数据项,用于表示当前类或接口中某个方法的完整描述。如果某个 method_info 结构
的 access_flags 项既没有设置 ACC_NATIVE 标志也没有设置 ACC_ABSTRACT 标志,
那么它所对应的方法体就应当可以被 Java 虚拟机直接从当前类加载,而不需要引用其它
类。method_info 结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、
实例初始化方法方法 和类或接口初始化方法方法。methods[]数组
只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法


attributes_count
属性计数器,attributes_count 的值表示当前 Class 文件 attributes 表的成员个
数。attributes 表中每一项都是一个 attribute_info 结构 的数据项

attributes[]
属性表,attributes 表的每个项的值必须是 attribute_info 结构(§4.7)。在本
规范里,Class 文件结构中的 attributes 表的项包括下列定义的属性:
InnerClasses 、EnclosingMethod 、Synthetic 、
Signature 、SourceFile ,SourceDebugExtension
 、Deprecated 、RuntimeVisibleAnnotations
 、RuntimeInvisibleAnnotations 以及
BootstrapMethods 属性。对于支持 Class 文件格式版本号为 49.0 或
更高的 Java 虚拟机实现,必须正确识别并读取 attributes 表中的 Signature
 、RuntimeVisibleAnnotations 和
RuntimeInvisibleAnnotations 属性。对于支持 Class 文件格式版
本号为 51.0 或更高的 Java 虚拟机实现,必须正确识别并读取 attributes 表中的
BootstrapMethods 属性。本规范要求任一 Java 虚拟机实现可以自动
忽略 Class 文件的 attributes 表中的若干(甚至全部)它不可识别的属性项。任何本
规范未定义的属性不能影响 Class 文件的语义,只能提供附加的描述信息 。





 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值