《深入理解java虚拟机》之类文件结构
2015-10-14 14:23
549 查看
Java虚拟机语言无关性
Java Class文件结构
1,头4个字节为魔数,用于确定这个文件是否为一个能被虚拟机接受的Class文件,值为:0xCAFEBABE
2,紧接着4个字节,5,6字节是次版本号,7,8字节是主版本号。高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生变化。
3,紧接着主次版本号之后的是常量池入口,1,常量池是Class文件结构中与其他项目关联最多的数据类型,2,占用Class文件空间最大的数据项目之一,3,在Cass文件中第一个出现的表结构数据项目;常量池的前两个字节是一项u2类型的数据,代表常量池容量计数器。这个容量计数是从1开始而不是0,把第0项常量空出来是为了满足 后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”。
常量池主要两大类常量:字面量和符号引用,字面量类似Java语言的常量概念,如文本字符串,被声明final的常量值等,符号引用属于编译原理方面的概念
三类常量:类和接口的全限定名,字段的名陈和描述符,方法的名称和描述符
Java代码在javac编译时不会连接,而是在虚拟机加载Class文件进行动态连接,即在Class文件中不会保存各个方法和字段的最终内存布局信息
常量池的每一项常量都是一个表,共有11种不同结构的表结构数据,这11种表的共同特点就是,表开始的第一位是一个u1类型的标志位,代表当前这个常量属于哪种常量类型。
4,接着2个字节,代表访问标志,用于识别一些类或接口层次的访问信息
5,接着是类索引,父类索引和接口索引集合;类,父类索引是一个u2(2个字节)类型的数据,索引接口是一组u2类型的数据集合,Class文件由这三项数据来确定这个类的继承关系
类索引用于确定这个类的全限定名
父类索引用于确定这个类的父类的全限定名
接口索引集合用来描述这个类实现哪些接口
根据顺序判断子父类
6,字段表集合,用于描述接口或类中声明的变量
7,方法表集合,如字段表一样,包括发那个问标志,名称索引,描述符索引,属性表集合
8,属性表集合
Code属性,Java程序方法体里面的代码经过javac编译器处理之后,最终变为字节码指令存储在Code属性内。Code属性出现在方法表的属性集合之中,但有特殊,如接口或抽象类中的方法不存在Code属性。
Exceptions属性,列举出方法中可能抛出的受查异常,即方法描述时在throws关键字后面列举的异常。
javap反编译之后的字节码文件
Java Class文件结构
1,头4个字节为魔数,用于确定这个文件是否为一个能被虚拟机接受的Class文件,值为:0xCAFEBABE
2,紧接着4个字节,5,6字节是次版本号,7,8字节是主版本号。高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生变化。
3,紧接着主次版本号之后的是常量池入口,1,常量池是Class文件结构中与其他项目关联最多的数据类型,2,占用Class文件空间最大的数据项目之一,3,在Cass文件中第一个出现的表结构数据项目;常量池的前两个字节是一项u2类型的数据,代表常量池容量计数器。这个容量计数是从1开始而不是0,把第0项常量空出来是为了满足 后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”。
常量池主要两大类常量:字面量和符号引用,字面量类似Java语言的常量概念,如文本字符串,被声明final的常量值等,符号引用属于编译原理方面的概念
三类常量:类和接口的全限定名,字段的名陈和描述符,方法的名称和描述符
Java代码在javac编译时不会连接,而是在虚拟机加载Class文件进行动态连接,即在Class文件中不会保存各个方法和字段的最终内存布局信息
常量池的每一项常量都是一个表,共有11种不同结构的表结构数据,这11种表的共同特点就是,表开始的第一位是一个u1类型的标志位,代表当前这个常量属于哪种常量类型。
4,接着2个字节,代表访问标志,用于识别一些类或接口层次的访问信息
5,接着是类索引,父类索引和接口索引集合;类,父类索引是一个u2(2个字节)类型的数据,索引接口是一组u2类型的数据集合,Class文件由这三项数据来确定这个类的继承关系
类索引用于确定这个类的全限定名
父类索引用于确定这个类的父类的全限定名
接口索引集合用来描述这个类实现哪些接口
根据顺序判断子父类
6,字段表集合,用于描述接口或类中声明的变量
7,方法表集合,如字段表一样,包括发那个问标志,名称索引,描述符索引,属性表集合
8,属性表集合
Code属性,Java程序方法体里面的代码经过javac编译器处理之后,最终变为字节码指令存储在Code属性内。Code属性出现在方法表的属性集合之中,但有特殊,如接口或抽象类中的方法不存在Code属性。
Exceptions属性,列举出方法中可能抛出的受查异常,即方法描述时在throws关键字后面列举的异常。
javap反编译之后的字节码文件
/* public class Test { public int getNum(int i) { return i + 1; } } */ public class Test extends java.lang.Object SourceFile: "Test.java" minor version: 0 major version: 50 //常量池 Constant pool: const #1 = class #2; const #2 = Asciz Test; const #3 = class #4; const #4 = Asciz java/lang/Object; const #5 = Asciz <init>; //实例构造器 const #6 = Asciz ()V; //void返回类型 const #7 = Asciz Code; //属性表Code属性 const #8 = Method #3.#9; //方法特征签名 java/lang/Object."<init>":()V const #9 = NameAndType #5:#6;// 方法名称和返回值"<init>":()V const #10 = Asciz LineNumberTable; //属性表源码行号和字节码指令对应表 const #11 = Asciz LocalVariableTable; //属性表方法局部变量表 const #12 = Asciz this; //Test类实例对象本身 const #13 = Asciz LTest;; //对象类型,Test类 const #14 = Asciz getNum; //方法名称 const #15 = Asciz (I)I; //方法参数列表为一个int类型和返回值为int类型 const #16 = Asciz i; //参数名称i const #17 = Asciz I; //参数类型int const #18 = Asciz SourceFile; const #19 = Asciz Test.java; //方法表 { //构造函数(默认构造方法) public Test(); Code: //属性表Code属性 Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 2: 0 LocalVariableTable: //属性表方法局部变量表 Start Length Slot Name Signature 0 5 0 this LTest; //自定义方法 public int getNum(int); Code: Stack=2, Locals=2, Args_size=2 0: iload_1 1: iconst_1 2: iadd 3: ireturn LineNumberTable: line 4: 0 LocalVariableTable: Start Length Slot Name Signature 0 4 0 this LTest; 0 4 1 i I }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- XP下使用虚拟机安装配置Solaris[多图]