JVM之类文件结构
来源:互联网 发布:防网络诈骗图片 编辑:程序博客网 时间:2024/06/08 18:47
代码编译的结果从本地机器码转变为字节码
1、概述
传统的将程序编写后需要进行编译成本地机器码,计算机只识别0和1,为了跨平台、跨语言,一种特殊的存储格式字节码出现了,编译的后的结果不再是机器码而是字节码。它可以被载入虚拟机当中。
2、Java语言规范、Java虚拟机规范
Java虚拟机是运行着操作系统之上的一个应用程序,在虚拟机之上不仅仅可以运行Java程序,还可以运行其它的程序。
3、Class类文件结构
解析Class文件的数据结构
以Java虚拟机规范为主线(指令、属性)
tips:任何一个Class文件都对应着唯一一个类或接口定义的信息,但是反过来说,类或接口并不一定都得定义在文件里(比如类或接口也可以通过类加载器直接生成。)
Class文件是一组以8位字节为基础单位的二进制流,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据, 这种伪结构中只有两种数据类型: 无符号数和表
无符号数:
无符号数属于基本的数据类型, 以u1、 u2、 u4、 u8来分别代表1个字节、 2个字节、 4个字节和8个字节的无符号
数, 无符号数可以用来描述数字、 索引引用、 数量值或者按照UTF-8编码构成字符串值。
表:
表是由多个无符号数或者其他表作为数据项构成的复合数据类型, 所有表都习惯性地以“ _info” 结尾。 表用
于描述有层次关系的复合结构的数据, 整个Class文件本质上就是一张表
Class文件格式解析:
java代码:
class TestClass{ private int m; private int inc(){ return m+1; }}
class字节码16进制表示:
—魔数:0xCAFEBABE
每个Class文件的头4个字节称为魔数( Magic Number) , 它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件
—Class文件版本:0x0000
第5和第6个字节是次版本号( Minor Version) , 第7和第8个字节是主版本号( Major Version)
—常量池:0x0013
常量池可以理解为Class文件之中的资源仓库
常量池中常量的数量是不固定的, 所以在常量池的入口需要放置一项u2类型的数据, 代表常量池容量计数值( constant_pool_count),这个容量计数是从1而不是0开始的
常量池中主要存放两大类常量:
字面量( Literal)
字面量( Literal),如文本字符串、 声明为final的常量值等。
符号引用( Symbolic References)
类和接口的全限定名( Fully Qualified Name)
字段的名称和描述符( Descriptor)
方法的名称和描述符
使用Javap命令输出常量表:
D:\java2>javap -verbose TestClassClassfile /D:/java2/TestClass.class Last modified 2017-12-15; size 275 bytes MD5 checksum 73de2fede86f2f34b6780d896a538428 Compiled from "TestClass.java"class TestClass SourceFile: "TestClass.java" minor version: 0 major version: 51 flags: ACC_SUPERConstant pool: #1 = Methodref #4.#15 // java/lang/Object."<init>":()V #2 = Fieldref #3.#16 // TestClass.m:I #3 = Class #17 // TestClass #4 = Class #18 // java/lang/Object #5 = Utf8 m #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 inc #12 = Utf8 ()I #13 = Utf8 SourceFile #14 = Utf8 TestClass.java #15 = NameAndType #7:#8 // "<init>":()V #16 = NameAndType #5:#6 // m:I #17 = Utf8 TestClass #18 = Utf8 java/lang/Object{ TestClass(); flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0}
—访问标志
两个字节代表访问标志( access_flags) , 这个标志用于识别一些类或者接口层次的访问信息, 包括: 这个Class是类还是接口; 是否定义为public类型; 是否定义为abstract类型; 如果是类的话, 是否被声明为final等
—类索引、 父类索引与接口索引集合
类索引( this_class) 和父类索引( super_class) 都是一个u2类型的数据, 而接口索引集合( interfaces)是一组u2类型的数据的集合, Class文件中由这三项数据来确定这个类的继承关系。 类索引用于确定这个类的全限定名, 父类索引用于确定这个类的父类的全限定名。
–字段表集合
字段表( field_info) 用于描述接口或者类中声明的变量。 字段( field) 包括类级变量以及实例级变量, 但不包括在方法内部声明的局部变量。
字段包含的的信息有: 字段的作用域( public、 private、 protected修饰符) 、 是实例变量还是类变量( static修饰符) 、 可变性( final) 、 并发可见性( volatile修饰符, 是否强制从主内存读写) 、 可否被序列化( transient修饰符) 、 字段数据类型( 基本类型、 对象、 数组) 、 字段名称。
—方法表集合
方法表的结构如同字段表一样, 依次包括了访问标志( access_flags) 、 名称索引( name_index) 、 描述符索引( descriptor_index) 、 属性表集合( attributes) 几项
—属性表集合
4、字节码指令
字节码与数据类型
加载和存储指令
运算指令
运算或算术指令用于对两个操作数栈上的值进行某种特定运算, 并把结果重新存入到操作栈顶。
类型转换指令
类型转换指令可以将两种不同的数值类型进行相互转换, 这些转换操作一般用于实现用户代码中的显式类型转换操作
对象创建与访问指令
对象创建后, 就可以通过对象访问指令获取对象实例或者数组实
例中的字段或者数组元素
操作数栈管理指令
将操作数栈的栈顶一个或两个元素出栈: pop、 pop2。
复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶: dup、 dup2、 dup_x1、 dup2_x1、 dup_x2、dup2_x2。
将栈最顶端的两个数值互换: swap
控制转移指令
条件分支: ifeq、 iflt、 ifle、 ifne、 ifgt、 ifge、 ifnull、 ifnonnull、 if_icmpeq、 if_icmpne、if_icmplt、 if_icmpgt、 if_icmple、 if_icmpge、 if_acmpeq和if_acmpne。
复合条件分支: tableswitch、 lookupswitch。
无条件分支: goto、 goto_w、 jsr、 jsr_w、 ret。
方法调用和返回指令
异常处理指令
同步指令
5、公有设计和私有实现
6、Class文件结构的发展
- JVM之类文件结构
- JVM之类文件结构
- JVM之类文件结构
- JVM之类文件结构
- JVM之类文件结构
- 深入理解JVM之类文件结构
- JVM之类文件结构——上篇(常量池)
- 深入理解JVM : class文件结构之类信息描述、字段表、方法表(2)
- JVM之类文件结构——下篇(字段、方法和属性)
- Java虚拟机之类文件结构
- 《深入理解java虚拟机》之类文件结构
- 深入理解JAVA虚拟机之类文件结构
- JVM class文件结构
- JVM类文件结构
- JVM类文件结构
- JVM--类文件结构
- jvm class文件结构
- 【JVM】类文件结构
- java 操作数字证书(x509)
- springmvc中controller 使用@RestController 和 @Controller 返回结果的区别
- 【数据挖掘 xgboost】特征的重要程度分析
- Maven使用中相关的问题
- leetCode#198. House Robber
- JVM之类文件结构
- IntelliJ IDEA添加jar包
- 我为什么使用maven
- GitHub最著名的20个Python机器学习项目!
- 【阿里在线技术峰会】何登成:AliSQL性能优化与功能突破的演进之路
- JSONDecodeError: Expecting value: line 1 column 1 (char 0)
- PrintWriter用法简析
- 购物车删除 筛选 排序
- Android FrameWork底层开发视频