Java字节码(.class文件结构)

简单记录.Class文件结构

ClassFile总体结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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];
}
  1. magic

    标识是否是class文件,正常class文件开头都是4个字节0xCAFEBABE.

  2. minor_version major_version

    编译成class文件的版本号,java6编译的major_version是0x32.

  3. constant_pool_count

    常量池的数量。

  4. constant_pool

    常量池,用于存放不同类型的数据,各种字符串,变量名称,变量类型都会存储在常量池。

    1
    2
    3
    4
    cp_info {
    u1 tag;
    u1 info[];
    }

    | Constant Type | Value |
    | —————————– | —– |
    | CONSTANT_Class | 7 |
    | CONSTANT_Fieldref | 9 |
    | CONSTANT_Methodref | 10 |
    | CONSTANT_InterfaceMethodref | 11 |
    | CONSTANT_String | 8 |
    | CONSTANT_Integer | 3 |
    | CONSTANT_Float | 4 |
    | CONSTANT_Long | 5 |
    | CONSTANT_Double | 6 |
    | CONSTANT_NameAndType | 12 |
    | CONSTANT_Utf8 | 1 |
    | CONSTANT_MethodHandle | 15 |
    | CONSTANT_MethodType | 16 |
    | CONSTANT_InvokeDynamic | 18 |

  5. access_flags

    指定接口和类的访问权限。

    | Flag Name | Value | Interpretation |
    | ————- | ———-| —————————————————–|
    | ACC_PUBLIC | 0x0001 | 公共,可以被外部包访问。 |
    | ACC_FINAL | 0x0010 | 不允许继承. |
    | ACC_SUPER | 0x0020 | 当被invoke.指令调用时,要特别对待超类方法。 |
    | ACC_INTERFACE | 0x0200 | 接口类。 |
    | ACC_ABSTRACT | 0x0400 | 抽象类,不能实例化。 |
    | ACC_SYNTHETIC | 0x1000 | 编译器生成,不在源代码中。 |
    | ACC_ANNOTATION| 0x2000 | 注解类型。 |
    | ACC_ENUM | 0x4000 | 枚举类型。 |

  6. this_class

    指向的是在静态区的CONSTANT_class_info结构体,说明当前的类名称。

  7. super_class

    0 或者 指向的是在静态区的CONSTANT_class_info结构体,说明当前的父类名称。

  8. interfaces_count

    说明接口的数量

  9. interfaces

    指向CONSTANT_class_info数组,记录当前类的实现接口。

  10. fields_count

    字段数量

  11. fields

    字段信息。

    1
    2
    3
    4
    5
    6
    7
    field_info {
    u2 access_flags;
    u2 name_index;
    u2 descriptor_index;
    u2 attributes_count;
    attribute_info attributes[attributes_count];
    }

    | Flag Name | Value | Interpretation |
    | ————- | ——— | —————————————— |
    | ACC_PUBLIC | 0x0001 | pubilc,包外可访问。 |
    | ACC_PRIVATE | 0x0002 | private,只可在类内访问。 |
    | ACC_PROTECTED | 0x0004 | protected,类内和子类中可访问。 |
    | ACC_STATIC | 0x0008 | static. 静态。 |
    | ACC_FINAL | 0x0010 | final. 常量。 |
    | ACC_VOLATILE | 0x0040 | 易变类型。 |
    | ACC_TRANSIENT | 0x0080 | 序列化忽略。 |
    | ACC_SYNTHETIC | 0x1000 | 编译器产生。 |
    | ACC_ENUM | 0x4000 | 枚举类型。 |

  12. methods_count

    方法数量

  13. methods

    方法信息。

    1
    2
    3
    4
    5
    6
    7
    method_info {
    u2 access_flags;
    u2 name_index;
    u2 descriptor_index;
    u2 attributes_count;
    attribute_info attributes[attributes_count];
    }

    | Flag Name | Value | Interpretation |
    | - | - | - |
    | ACC_PUBLIC | 0x0001 | 公共方法
    | ACC_PRIVATE | 0x0002 | 私有方法
    | ACC_PROTECTED | 0x0004 | 保护方法
    | ACC_STATIC | 0x0008 | 静态方法
    | ACC_FINAL | 0x0010 | 不允许重写
    | ACC_SYNCHRONIZED | 0x0020 | Declared synchronized; invocation is wrapped by a monitor use.
    | ACC_BRIDGE | 0x0040 | 编译器生成
    | ACC_VARARGS | 0x0080 | 可变参数
    | ACC_NATIVE | 0x0100 | Native方法
    | ACC_ABSTRACT | 0x0400 | 抽象方法
    | ACC_STRICT | 0x0800 | 浮点数模型2.8.2
    | ACC_SYNTHETIC | 0x1000 | 编译器生成方法

  14. attributes_count

    属性数量

  15. attributes

    属性信息

静态区结构体

  1. CONSTANT_Class_info 代表接口或者类

    1
    2
    3
    4
    CONSTANT_Class_info {
    u1 tag; // 7
    u2 name_index; // 指向静态区的CONSTANT_Utf8_info存储名称。
    }
  2. CONSTANT_Fieldref_info 用于记录字段信息

    1
    2
    3
    4
    5
    CONSTANT_Fieldref_info {
    u1 tag; // 9
    u2 class_index; // 指向的可能是classtype或者interfacetype
    u2 name_and_type_index; // 指向 CONSTANT_NameAndType_info 字段描述或者方法描述
    }
  3. CONSTANT_Methodref_info 用于记录方法信息

    1
    2
    3
    4
    5
    CONSTANT_Methodref_info {
    u1 tag; // 10
    u2 class_index; // classtype
    u2 name_and_type_index; // 如果是<开始的,那么一定是void <init>的方法
    }
  4. CONSTANT_InterfaceMethodref_info 用于记录接口中的方法信息

    1
    2
    3
    4
    5
    CONSTANT_InterfaceMethodref_info {
    u1 tag; // 11
    u2 class_index; // interfacetype
    u2 name_and_type_index; // 指向 CONSTANT_NameAndType_info 字段描述或者方法描述
    }
  5. CONSTANT_String_info 记录字符串。

    1
    2
    3
    4
    CONSTANT_String_info {
    u1 tag; // 8
    u2 string_index; // 指向CONSTANT_Utf8_info
    }
  6. CONSTANT_Integer_info 记录Int类型常量

    1
    2
    3
    4
    CONSTANT_Integer_info {
    u1 tag; // 3
    u4 bytes; // 整型常量
    }
  7. CONSTANT_Float_info 记录浮点数常量

    1
    2
    3
    4
    CONSTANT_Float_info {
    u1 tag; // 4
    u4 bytes; // 浮点常量
    }

    几个特殊值:

    0x7f800000 => Float.POSITIVE_INFINITY

    0xff800000 => Float.NEGATIVE_INFINITY

    0x7f800001 to 0x7fffffff => Float.NaN

    0xff800001 to 0xffffffff => Float.NaN

    1. CONSTANT_Long_info 记录long类型常量

      1
      2
      3
      4
      5
      CONSTANT_Long_info {
      u1 tag; // 5
      u4 high_bytes; // 高4位
      u4 low_bytes; // 低4位
      }
  8. CONSTANT_Double_info 记录Double类型常量

    1
    2
    3
    4
    5
    CONSTANT_Double_info {
    u1 tag; // 6
    u4 high_bytes; // 双精度浮点的高四位值
    u4 low_bytes; // 双精度浮点的低四位值
    }

    几个特殊值:

    0x7ff0000000000000L => Double.POSITIVE_INFINITY

    0xfff0000000000000L => Double.NEGATIVE_INFINITY

    0x7ff0000000000001L to 0x7fffffffffffffffL => Double.NaN

    0xfff0000000000001L to 0xffffffffffffffffL => Double.NaN

  9. CONSTANT_NameAndType_info 记录方法或字段的名称(name)和描述符(descriptor)

    1
    2
    3
    4
    5
    CONSTANT_NameAndType_info {
    u1 tag; // 12
    u2 name_index; // CONSTANT_Utf8_info
    u2 descriptor_index; // CONSTANT_Utf8_info
    }
  10. CONSTANT_Utf8_info 记录字符串。

    1
    2
    3
    4
    5
    CONSTANT_Utf8_info {
    u1 tag; // 1
    u2 length; // 长度
    u1 bytes[length]; // 字符串数据。
    }
  11. CONSTANT_MethodHandle_info 代表方法句柄

    1
    2
    3
    4
    5
    CONSTANT_MethodHandle_info {
    u1 tag; // 15
    u1 reference_kind; // 1-9的值
    u2 reference_index; // 不同的reference_kind值有不同的行为。
    }
  12. CONSTANT_MethodType_info

    1
    2
    3
    4
    CONSTANT_MethodType_info {
    u1 tag; // 16
    u2 descriptor_index; // CONSTANT_Utf8_info
    }
  13. CONSTANT_InvokeDynamic_info

    1
    2
    3
    4
    5
    CONSTANT_InvokeDynamic_info {
    u1 tag; // 17
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
    }