鲁迅曾经说过:代码编译的结构从本地机器码转变为字节码,是存储格式发展的一小步,确是编程语言发展的一大步。

一.无关性的基石

  Java设计者在最初就承诺过“In the future, we will consider bounded extensions to the Java virtual machine to privide better support for other languages”(在未来,我们会对Java虚拟机进行适当的扩展,以便更好地支持其他语言运行于JVM之上)。

  时至今日,在Java语言之外已经有大批在Java虚拟机之上运行的语言,如Clojure、Groovy、JRuby、Jython、Scala等。

  Java虚拟机不和包括Java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联。

     图:java虚拟机提供的语言无关性

三.Class类文件的结构

  Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符。

  Java文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构只有两种数据:无符号数和表。

  无符号数属于基本的数据类型(八种),以u1,u2,u4,u8来分别表示1个字节、2个字节、4个字节、8个字节的无符号数。

  表是由多个无符号数或者其他表作为数据项构成的符合数据类型。整个Class文件本质上就是一张表

    图:Class文件格式

  无论是无符号数还是表,当需要描述同一类型但数量不一定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这是称这一系列连续的某一类型的数据为某一类型的集合。

1.  魔数(Magic Number)与Class文件的版本

  每个Class文件的头4个字节(u4)称为魔数(),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。

  在魔数之后的4个字节存储的Class文件的版本号:第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。

  Java的版本是从45开始的。高版本可以向下兼容。

  可以用十六进制编辑器WinHex打开class文件看看:

package com.yuanbaopu.fide.chief.service;

import com.yuanbaopu.fide.common.FileDto;

public interface AccountService {

    FileDto getAccountFile(String uuid);

}

这里的主版本是51,从45(JDK1.1)开始的话,51就对应着JDK1.7。

    图:Class文件版本号

2.  常量池

  紧接着版本号之后的是常量池入口,常量池可以理解为Class文件之中的资源仓库,是占用Class文件空间最大的数据项目之一,也是Class文件中第一个出现的表类型数据项目。

  由于常量池数量不是固定的,所以在常量池的入口需要放置一项u2类型的数据(可以对照Class文件格式图方便了解),代表常量池计数器(constant_pool_count)。与Java习惯不一样的是,这个容器的计数是从1开始而不是0,设计者把0空出来有特殊的考虑:“不引用任何一个常量池项目”。 如下图,我们可以知道常量池共有9项常量,除去默认的一个,则还有8项常量。

  常量池中每一项常量都是一个表,每个表都有一个共同特点,就是表开始的第一位是一个u1类型的标志位,代表当前的这个常量属于哪种常量类型。

  不难发现,第一个标志为“7”对应着“CONSTANT_Class_info”,而“CONSTANT_Class_info”类型的常量结构如下:

  tag是标志位,上面已经讲过了,它用于区分常量类型;name_index是一个索引值,它指向常量池中一个“CONSTANT_Utf8_info”类型的常量,此常量代表了这个类或接口的全限定名。

  我们再看一下“CONSTANT_Utf8_info”型常量的结构

并贴上常量池的14种常量项的结构总表:

  后面的其他几个常量,为了避免占用过多版面,我们使用JDK的bin目录下的一个工具:javap。

  使用javap工具的 -verbose参数输出AccountService.class文件字节码内容。

  

我们看一个详细的对照例子(图片太小可以右键“在新标签页中打开图片”):看一下、看一下、看一下......

3.  访问标志(access_flags)

4.  类索引(this_class)、父类索引(super_class)与接口索引(interfaces)集合

  类索引和父类索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据的集合,Class文件中由这三项数据来确定这个类的继承关系。

5.  字段表(field_info)集合

  字段访问标志:

  

  

  对于数组类型,每一个维度将使用一个前置的“[”字符来描述,如定义一个“java.lang.String[][]”将被记录为“[[java.lang.String”

6.  方法表集合

  方法访问标志:

7.  属性表(attribute_info)集合

  虚拟机规范预定义属性:

  

  

  注意:有个小知识:在任何实例方法里面,都可以通过“this”关键字访问到此方法所属的对象。这个访问机制对Java程序编写很重要,而它的实现却很简单,

  仅仅是通过Javac编译器编译的时候把对this关键字的访问转变为对一个普通方法参数的访问,然后在虚拟机调用实例方法时自动传入此参数而已。因此在实例方法的局部变量表中至少会存在一个指向当前对象实例的局部变量。

【JVM.5】类文件结构的更多相关文章

  1. 深入理解JVM(六)类文件结构

    6.1 关于类文件 1.class文件的一次编译,到处运行的跨平台性: 2.JVM不止有跨平台性,还有跨语言性,不管是JRuby还是Groovy写出来的程序,只要编译出符合JVM规范的class文件就 ...

  2. JVM(4) 类文件结构

    一.实现“平台无关性” 字节码(ByteCode)存储格式和虚拟机是实现语言无关性的基础.Java虚拟机不和包括Java在内的任何语言绑定,它只与“Clas”文件这种特定的二进制文件格式所关联,Cla ...

  3. JVM小结--类文件结构

    字节码是构成Java平台无关性的基石.实现语言无关性的基础是虚拟机和字节码存储格式. Java语言中的各种变量.关键字和运算符的语义最终是由多条字节码命令组成,因此字节码命令所能提供的语义描述能力肯定 ...

  4. JVM学习笔记(三):类文件结构

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...

  5. jvm 类文件结构学习

    本文以代码示例来学习 java 类文件的结构,其中对类文件结构的学习均来自周志明先生所著的 <深入理解 Java 虚拟机>一书,在此表示诚挚的感谢. 代码如下: package com.r ...

  6. 【搞定Jvm面试】 面试官:谈谈 JVM 类文件结构的认识

    类文件结构 一 概述 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机.Java 语言通过字节码的方式,在一定程度上解决 ...

  7. 四、JVM — 类文件结构

    类文件结构 一 概述 二 Class 文件结构总结 2.1 魔数 2.2 Class 文件版本 2.3 常量池 2.4 访问标志 2.5 当前类索引,父类索引与接口索引集合 2.6 字段表集合 2.7 ...

  8. jvm(4):类文件结构

    typora-root-url: ./ 类文件结构 魔数Magic Number 每个Class文件的头4个字节是魔数.值为0xCAFEBABE 唯一作用:确定这个文件是一个能被虚拟机接受的Class ...

  9. JVM类文件结构

    作为一名Java后台开发的程序员, 深入理解JVM, 重要性不言而喻, 这篇文章主要是记录JVM类文件结构相关知识. 2. 实例 这部分比较抽象, 所以以实例的形式来学习. 这部分作为资料, 以便后面 ...

  10. JVM学习第三天(JVM的执行子系统)之开篇Class类文件结构

    虽然这几天 很忙,但是学习是不能落下的,也不能推迟,因为如果推迟了一次,那么就会有无数次;加油,come on! Java跨平台的基础: 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节 ...

随机推荐

  1. dubbo-admin管理控制台的安装部署(最简单)

    Dubbo-admin最简单的安装部署,十分钟就能搞定! 网上找的安装教程虽说详细,但是就是因为详细操作起来而显得繁琐.今天,我帮大家跳过这些繁琐的步骤,简单快捷的安装部署dubbo-admin. 1 ...

  2. Java动态生成类以及动态添加属性

    有个技术实现需求:动态生成类,其中类中的属性来自参数对象中的全部属性以及来自参数对象properties文件. 那么技术实现支持:使用CGLib代理. 具体的实现步骤: 1.配置Maven文件: &l ...

  3. psotgresql之大小写

    框中内容来自<PostgreSQL数据库对象名大小写敏感> 网址:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=812 ...

  4. 【第八篇】SAP ABAP7.5x新语法之F4增强【续】

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:SAP ABAP7.5x系列之F4增强[续]   ...

  5. U盘内容被病毒隐藏的解决办法(亲测可用)

    前几天用U盘的时候不小心感染上了病毒,用自己的电脑打开后里面只剩下一个U盘的快捷方式,选中显示隐藏文件之后依然没有任何显示,但是查看U盘的属性的时候可以看到,U盘已经使用了300多M,所以就上网查了一 ...

  6. C语言四舍五入

    //今天遇到了四舍五入的问题,这些问题如果不看别人的真的难想出这么巧妙的方法啊.努力积累,早日成为大佬. int i = (int)(a + 0.5) ////小数部分大于0.4,加上0.5就会超过整 ...

  7. SqlBulkCopy批量添加

    /// <summary> /// 添加数据 /// 注:DataTable列名必须和数据库列名一致 /// </summary> /// <returns>< ...

  8. [题目] luogu P2061 [USACO07OPEN]城市的地平线City Horizon

    算法 线段树 + 离散化 思路 对\((x,y,h)\)的左右端点\(x,y\)进行离散化,离散化前的原值记为\(val[i]\),对每个矩形按高度\(h\)从小到大排序. 设离散化后的端点有\(M\ ...

  9. kubelet 初始化过程

    kubelet 初始化过程 . kubelet 启动 . kubelet认为,它并没有有一个kubeconfig文件 . kubelet搜索并查找bootstrap-kubeconfig文件 . ku ...

  10. Arduino IDE for ESP8266 项目(3)创建AP+STA

    官网API:http://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html STA (客户端)手机连接路由器 S1 *简 ...