字节码
简介
- 编译器将Java源码编译成符合Java虚拟机规范的字节码文件。
- 字节码组成结构比较特殊,其内部不包含任何分隔符区分段落。
- 一组8位字节单位的字节流组成了一个完整的字节码文件。
字节码内部组成结构
- 《Java虚拟机规范 Java SE7》中,每一个字节码文件都对应着全局唯一的一个类或者接口的定义信息。
- 本书用项(item)表示用于描述类结构格式的内容
- 每一项包括类型、名称以及该项的数量。
- 各项包含在字节码文件中,按严格的顺序连续存放。
- 该结构只有两种数据结构,分别为无符号数和表。
类型 | 说明 |
u1 | 1个字节,无符号类型 |
u2 | 2个字节,无符号类型 |
u4 | 4个字节,无符号类型 |
u8 | 8个字节,无符号类型 |
- 表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表的后缀都是_info,并且字节码文件实质上就是一张表。
每个字节码文件对应着一个ClassFile文件的结构,如下:
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]; }
ClassFile结构描述
- ①magic
- 一个有效的字节码文件的前四个字节为0xCAFEBABE,称为magic number
- ②minor_version(次版本号)和major_version(主版本号)
- 如果主版本号为M,次版本号为m,那么字节码文件版本号为M.m
- 低版本的JVM不能处理由高版本JVM编译生成的字节码,会抛出java.lang.UnSupportedClassException,不过高版本的JVM可以兼容由低版本JVM编译出来的字节码文件。
- ③constant_pool_count(常量池计数器)和constant_pool(常量池)
- 常量池是字节码文件中非常重要的数据项,也是与其他项关联最多和占用字节码空间最大的数据项。
- 常量池主要用于存放字面量(Literal)和符号引用(Symbolic References)两大类数据常量,其访问方式是通过索引来进行访问的。
- 常量池中存放的字面量由文字字符串、final常量值等构成,而符号引用则包括了类和接口的全限定名(Fully Qualified Name)、字段的名称和描述符(Descriptor),以及方法的名称和描述符。
类型 | tag | 描述 |
CONSTANT_Utf8_info | 1 | UTF-8编码的字符串 |
CONSTANT_Integer_info | 3 | 整形字面值 |
CONSTANT_Float_info | 4 | 单精度浮点数类型字面值 |
CONSTANT_Long_info | 5 | 长整型字面值 |
CONSTANT_Double_info | 6 | 双精度浮点类型字面值 |
CONSTANT_Class_info | 7 | 类或者接口的符号引用 |
CONSTAN |