java虚拟机规范中的java虚拟机的跨语言性及跨平台性,多半归功于定义中的Class文件,Class文件解耦了虚拟机平台的具体实现与具体的编程语言,也业务开发角度理解,能够将它抽象成接口对接文档(固然只是为了方便理解),既然是已经拟定的文档,那么必然存在必定的规则,在了解具体Class文件规范以前须要对Class文件有一个总体的认识。java
首先Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有任何分隔符,这使得整个Class文件中存储的内容几乎所有是程序运行的必要数据,没有空隙存在。当须要须要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。编程
根据java虚拟机规范的规定,Class文件格式采用相似于c语言中结构体的伪结构(仅仅是数据组合的一种既定方式)来存储数据,在该伪结构中只有两种数据类型:无符号数和表。安全
无符号数属于基本的数据类型,以u一、u二、u四、u8来分别表明1个字节、2个字节、4个字节、和8个字节的无符号数,经常使用于表述数字(好比常量池的count、方法表count、属性表count等)、索引引用、数值量或按照UTF-8编码构成的字符串值。编程语言
表在结构上是由无符号数和其余表构成的用语表述具备层次关系的复合结构,整个class文件也能够当作是一张特殊的表。性能
在介绍具体的Class文件结构以前,须要提醒的是class文件中对于字节码的顺序、长度都有严格的定义,具体的虚拟机实现必须遵循这样的规范(否则一次编译处处运行只能是梦想),固然Class文件规范中也容许虚拟机实如今遵循java标准虚拟机规范的前提下自由定义其余属性以提升虚拟机在某方面的性能。编码
Class文件结构:spa
不管是无符号数仍是表,当须要描述同一类型但数量不定的多个数据时,常常会使用一个前置的容量计数器加若干个连续的数据项的形式(这应该比较好理解,不少协议中都用了相似的思想,在数据报文头中先告诉接受端报文内容的总体信息,根据这些信息去解析报文数据,如netty中的编码器和解码器、http协议等),这时称这一系列连续的某一类型的数据为某一类型的集合。.net
详解Class文件结构:netty
为方便进一步理解,将使用下面的例子进行讲解:code
package org.lucas.clazz; /** * Created by BG260733 on 2017-04-09. */ public class TestClass { private int n; private static final int m = 5; public int inc() { return m + n; } }
说明:如下class文件均由winHex十六进制打开。
magic:
每一个class文件的头4个字节称为魔数(Magic Number),它的惟一做用时肯定这个文件是否为一个能被虚拟机接受的class文件(不表明能成功解析)。不少文件存储标准中都是在文件内容中嵌入魔术来进行身份识别,之因此不使用文件名(包括后缀)来做为文件的识别方式,主要是出于安全方面的考虑,文件名可能会被外部频繁改动。Class文件的魔术值为:OxCAFEBABY,是否是自带浪漫气息。
minor_version
仅接着魔数后面的第5个和第6个两个字节,表示可以解析执行该class文件的虚拟机次版本号。
major_version
第7个和第8个两个字节,表示可以解析执行该class文件的虚拟机主版本号。
下表列出了从JDK1.1到JDK1.7,主流JDK版本编译器输出的默认和可支持的Class文件版本号。
-target标志表示容许编译器生成特定版本的Java类文件格式。
-source标志表示容许编译器将新的语言构造(如Lambda表达式、try-with-resources以及switch中使用字符串等等)看作错误。一些新语言特性(好比Lambda表达式)须要使用特定的字节码功能(好比invokedynamic),所以,-source指定的版本比-target指定的版本还新每每是不可能的。
博主本打算将Class文件全部内容由一篇文章讲述清楚、但实际编写过程当中发现待表述的信息量仍是太大,为了方便读者阅读,特将此篇分为五到六篇文章,未完待续~