zoukankan      html  css  js  c++  java
  • Java 类文件结构

    Class类文件时一组以字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,没有任何分隔符。对于大于8位的数据均采用大头方式储存,文件中只有无符号数和表两种结构

    无符号数有u1,u2,u4,u8,即1,2,4,8位字节,可以用来描述数字,索引引用,数量值或按照utf8编码的字符串值

    表是由一组无符号数组成的结构,所有表均以_info结尾,整个Class文件本质上就是一张表,其按照以下数据项依次排列:

    magic-->minor_version-->major_version-->constant_pool_count-->constant_pool-->access_flags-->this_class

    -->super_class-->interfaces_count-->interfaces-->fields_count-->fields-->methods_count-->methods-->attributes_count-->attributes

    1.magic u4

     魔数,Class文件以0xCAFEBABE开头

    2.minor_version u2  major_version u2

    次版本号和主版本号   jdk1.8的主版本号位52

    3.constant_pool_count u2  constant_pool 

    常量池,constant_pool_count代表常量池计数器,从1开始计数,所以常量池中常量个数等于constant_pool_count - 1,用0来表示“不引用任何常量池项目”

    常量池主要存放字面量(Literal)和符号引用

    字面量:字符串,被声明为final的值等

    符号引用:包含以下三类常量

    1)类和接口的全限定名

    2)字段的名称和描述符

    3)方法的名称和描述符

    常量池中每一项都是一个表,一共有11中结构不同的数据表,以下是每个表所对应的标志(tag,类型为u1)

    标志 类型(CONSTANT_xxx_info) 描述 结构(第一个字节均为对应的tag)
    1 Utf8   UTF-8编码的字符串 length(u2) + bytes(length)
    3 Integer  整型字面量 bytes(ur)
    4 Float   浮点型字面量 bytes(u4)
    5 Long   长整型字面量 bytes(u8)
    6 Double   双精度浮点型字面量 bytes(u8)
    7 Class   类或接口的符号引用 index(u2)
    8 String   字符串类型字面量 index(u2)
    9 Fieldref   字段的符号引用 index(u2) + index(u2)
    10 Methodref 类中方法的符号引用 index(u2) + index(u2)
    11 InterfaceMethodref 接口中的符号引用 index(u2) + index(u2)
    12 NameAndType 字段或方法的部分符号引用 index(u2) + index(u2)

    4.access_flags u2

    访问标志,识别类或接口的访问信息,目前有以下8个标志:

    标志名称 标志值 含义
    ACC_PUBLIC 0X0001 是否是public
    ACC_FINAL 0X0010 是否是final,只有类才可能有
    ACC_SUPER 0X0020 jdk1.2之后都有
    ACC_INTERFACE 0X0200 标志这是一个接口
    ACC_ABSTRACT 0X0400 对于接口或抽象类为真,其他类为假
    ACC_SYNTHETIC 0X1000 标志该类并非由用户代码产生
    ACC_ANNOTATION 0X2000 标识这是一个注解
    ACC_ENUM 0X4000 标识这是一个枚举

    access_flag的值等于标志为真的标志值相与,例如0x0001|0x0010 = 0x0011 表示是public final的

    5.this_class  u2  super_class  u2

    类索引和父类索引,因为一个类只有一个父类,所以均用u2表示(与interface相对比),依据该值可以在常量池找到一个全限定名字符串

    6.interfaces_count u2  interfaces

    接口索引,以u2类型开头表示该类有interfaces_count个接口,然后依次是interfaces_count个u2类型值,依据该值可以在常量池找到一个全限定名字符串

    7.fields_count u2  fields

    字段表,用于描述接口或者类中声明的变量,包括以下几个项目:

    1)access_flags:

    字段修饰符,各种表示对应的标志值

    标志名称 标志值
    ACC_PUBLIC 0X0001
    ACC_PRIVATE 0X0002
    ACC_PRITECTED 0X0004
    ACC_STATIC 0X0008
    ACC_FINAL 0X0010
    ACC_VOLATILE 0X0400
    ACC_TRANSIENT 0X0800
    ACC_SYNTHETIC 0X1000
    ACC_ENUM 0X4000

    2)name_index  descriptor_index

    字段的简单名称及字段和方法的描述符

    几个名词解释:

    全限定符——如com/xiao/helloworld/Test

    简单名称——定义变量i,i为简单名称

    字段和方法的描述符——描述字段的数据类型,方法的参数列表(包括数量,类型及顺序),返回值

    数据类型对应规则为:基本类型以及void用一个大写字母来表示(类型的第一个字母大写,除了long为J,boolean为Z);对于对象类型,使用字母L加上对象的全限定类名表示;对于数组,每一维度使用一个前置的[

    描述方法时:按照先参数列表后返回值描述,参数列表严格按顺序放置在()中,如(IIFZ)V表示void xxx(int x,int x,float x,boolean x)

    3)attributes_count  attributes

    可能有的属性,例如 final static int m = 456;就会存放一个ConstantValue,其指向常量456;

    8.methods_count  methods

    方法表集合,与字段表的结构基本一样的,除了access_flags标志值有变化,变化如下:

    标志名称 标志值
    ACC_PUBLIC 0X0001
    ACC_PRIVATE 0X0002
    ACC_PRITECTED 0X0004
    ACC_STATIC 0X0008
    ACC_FINAL 0X0010
    ACC_SYNCHRONIZED 0X0020
    ACC_BRIDGE 0X0040
    ACC_VARARGS 0X0080
    ACC_NATIVE 0X0100
    ACC_ABSTRACT 0X0400
    ACC_STRICT 0X0800
    ACC_SYNTHETIC 0X1000

    如果父类方法没有在子类中被重写,那么方法表中不会出现父类的方法信息;另外也有可能会出现编译器自动添加的方法,如<clinit>(类的构造方法)<init>(实例构造方法)

    方法具体的代码被编译成字节码指令,存放在方法属性表内一个名为Code的属性里面

    9.attributes_count  attributes

    属性表,包括很多个属性,例如Code,constantValue,Exceptions(可能抛出的异常种类和数量 ,throws)等等

  • 相关阅读:
    算法初步——哈希表B.1038统计同成绩学生
    算法初步——哈希表B10133.旧键盘打字 (注意bool型数组的赋值为true的方法)
    算法初步——哈希表B1029/A1084. 旧键盘
    算法初步——排序 A1012.The Best Rank(25)
    《思维导图》——东尼博赞
    算法初步——排序B1015/A1062.德才论
    入门模拟——(字符串处理)A1001. A+B Format(20)
    RMQ问题(线段树+ST算法)
    PKU 2406 Power Strings(KMP最长循环不重叠字串)
    KMP算法 kuangbin
  • 原文地址:https://www.cnblogs.com/xiao-ji-xiang/p/9837445.html
Copyright © 2011-2022 走看看