好文推荐(图文并茂):http://blog.csdn.net/luanlouis/article/details/39960815
Question:Java程序如何运行的?
-见下图
Question:为什么使用虚拟机?
-1。跨平台。(CPU指令集不同,操作系统接口不同)
-2。效率更高。(相对于解释型语言)
-3。抽象层次高,更容易编程
Part 1:
Class 文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。
EmployeeV1.class
与下面格式对应
前10个字节详解
Part 2:
53个常量结束后是:访问标志(access_flags)
图中,只有ACC_PUBLIC、ACC_SUPER标志为真,其他为假,所以access_flags = 0x0001|0x0020 = 0x0021
Part 3:
访问标志后是:类索引(this_class)、父类索引(super_class)与接口索引集合(interfaces)
3个u2类型的值分别为:0x0001、0x0003、0x0000,也就是类索引为1,父类索引为3,接口索引集合为0。
由于Java语言不允许多充继承,所以父类索引只有一个,出来java.lang.Object之外,所有的Java类都有父类,因此出来java.lang.Object 外,所有Java类的父类索引都不为0。
如果该类没有实现任何接口,则该计数器值为0,后面接口的索引表不再占用任何字节。
Part 4:
类和接口后是:字段表集合
Q:什么是字段表?
A:字段表(field_info)用于描述接口或者类中声明的变量。(字段(field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量)
Part 5:
字段表后是:方法表集合
顾名思义:即对方法的描述
方法里的Java代码,经过编译器编译成字节码指令后,存放在方法属性表集合中一个名为”Code”的属性里面,属性表作为Class文件格式中最具扩展性的一种数据项目。
关于code_length:虽然它是一个u4类型的长度值,理论上最大值可以达到2^32 - 1,但是虚拟机规范中明确限制了一个方法不允许超过65535条字节码指令,即它实际只使用了u2的长度,如果超过这个限制,Javac编译器也会拒绝编译。
例如:在编译一个很复杂的JSP文件时候,某些JSP编译器会把JSP内容和页面输出的信息归并于一个方法之中,就可能因为方法生成字节码超长的原因而导致编译失败。
实战
①javap:这工具在JDK的bin目录中,是专门用于分析Class文件字节码的工具。
②使用javap命令输出常量表:
Tip:若出现 “警告: 二进制文件EmployeeV1包含com.donaldy.jvm.test.EmployeeV1” 这是包名。
③对照表找词: