在 Java 中,JVM 能够理解的代码就叫作字节码
(即扩展名为 .class
的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言经过字节码的方式,在必定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特色。因此 Java 程序运行时比较高效,并且,因为字节码并不针对一种特定的机器,所以,Java 程序无须从新编译即可在多种不一样操做系统的计算机上运行。java
Class文件字节码结构组织示意图 编码
紧接着主次版本号以后的是常量池,常量池的数量是 constant_pool_count-1(常量池计数器是从1开始计数的,将第0项常量空出来是有特殊考虑的,索引值为0表明“不引用任何一个常量池项”)。spa
常量池主要存放两大常量:字面量和符号引用。字面量比较接近于 Java 语言层面的的常量概念,如文本字符串、声明为 final 的常量值等。而符号引用则属于编译原理方面的概念。包括下面三类常量:类和接口的全限定名 字段的名称和描述符 方法的名称和描述符操作系统
常量池中每一项常量都是一个表,这14种表有一个共同的特色:开始的第一位是一个 u1 类型的标志位 -tag 来标识常量的类型,表明当前这个常量属于哪一种常量类型.code
类型 | 标志(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 | 类或接口的符号引用 |
CONSTANT_String_info | 8 | 字符串类型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符号引用 |
CONSTANT_Methodref_info | 10 | 类中方法的符号引用 |
CONSTANT_InterfaceMethodref_info | 11 | 接口中方法的符号引用 |
CONSTANT_NameAndType_info | 12 | 字段或方法的符号引用 |
CONSTANT_MothodType_info | 16 | 标志方法类型 |
CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |
4.在常量池结束以后,紧接着的两个字节表明访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括:这个 Class 是类仍是接口,是否为 public 或者 abstract 类型,若是是类的话是否声明为 final 等等。blog
5.类索引用于肯定这个类的全限定名,父类索引用于肯定这个类的父类的全限定名,因为 Java 语言的单继承,因此父类索引只有一个,除了 java.lang.Object
以外,全部的 java 类都有父类,所以除了 java.lang.Object
外,全部 Java 类的父类索引都不为 0。继承
接口索引集合用来描述这个类实现了那些接口,这些被实现的接口将按implents
(若是这个类自己是接口的话则是extends
) 后的接口顺序从左到右排列在接口索引集合中。索引
6.字段表(field info)用于描述接口或类中声明的变量。字段包括类级变量以及实例变量,但不包括在方法内部声明的局部变量。接口
field info(字段表) 的结构:ip
public
,private
,protected
修饰符),是实例变量仍是类变量(static
修饰符),能否被序列化(transient 修饰符),可变性(final),可见性(volatile 修饰符,是否强制从主内存读写)。上述这些信息中,各个修饰符都是布尔值,要么有某个修饰符,要么没有,很适合使用标志位来表示。而字段叫什么名字、字段被定义为何数据类型这些都是没法固定的,只能引用常量池中常量来描述。
7.方法表集合