`
cgaolei
  • 浏览: 57357 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

Java类文件格式快速入门

阅读更多

原文地址:http://viralpatel.net/blogs/2009/01/tutorial-java-class-file-format-revealed.html

原作者:Viral Patel

译者:Alan Gao @ cgaolei.iteye.com

 

译者序:

最近工作解决一个问题时需要用到Java bytecode的知识,临阵磨枪学习了一下,还真的对java bytecode产生的很大的兴趣,打算平时再深入研究一下。学字节码时,我是先从类文件的格式入手的。当然,学习这方面东西,最权威不过的还得是<<Java虚拟机规范了>>:http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html。 只不过那里写的过于正规详细,需要一定时间理解和消化。随即搜索了一下相关的文章,于是找到了Viral Patel的这篇教程。文章图文并茂,简单易懂,短短几句话就含盖了重要的知识点,可以让人快速勾画出类文件的轮廓。做为快速入门和大概了解类文件的教程最合适不过了。又搜索了一下中文的资料,相关的文章也不少,但感觉都没有这篇适合。所以翻译一下做为参考。

 

译文:

 

我们所看到的Java字节码是被封装在一个类文件中(扩展名为.class)。在这个教程中,就让我们来看看类文件的内部构造。

数据是如何被写入类文件以及类文件的格式是怎样的呢,让我们首先图解看一看Java类文件。

 

Java类文件结构示意图:

 

上图描绘的Java类文件被分为了不同的区段,包括魔术码(magic)、版本(version)、常量池(constant pool)、访问标识(access flags)、(this)类、(super)类、接口(interfaces)、域(fields)、方法(methods)和属性(attributes)。

 

首先Java类的长度在它被加载之前是未知的,因为类中含有可变长度的区段,如常量池、方法、属性等这些区段。但这些区段的开头字节都是该区段的大小或长度信息,这样JVM在实际装载它们之前会知道这些可变长度区段的大小。写入类文件的数据是以紧凑的单字节存放的,这有助于减小类文件的大小。Java类文件中不同区段的顺序是严格规定的,以便JVM可以按其顺序载入不同区段。让我们详细看看类文件中的每个组成部分。

 

(译者注:这十个区段M agic, V ersion, C onstant pool, A ccess flags, T his, S uper, I nterfaces, F ields, M ethods, A ttributes 连起来可以用一个句英文方便记忆它们的顺序:M y V ery C ute A nimal T urns S avage I n F ull M oon A reas . 我非常可爱的小动物在滿月的地方变得疯狂。)

魔术码(magic)区段

魔术码是用来识别文件格式以便区别于其他格式。类文件的前四个字节,也就是魔术码,0xCAFEBABE。(译者注:16进制编码的写法即是英文单词CAFE BABE[咖啡宝贝],以方便记忆)


 

版本号(version)区段

 

紧跟着的四个字节包含了类文件的主要和次要版本号 。版本号数字可使JVM核实并确定类文件是否兼容。如果版本号大于JVM可以加载的版本号,类文件将无法被载入。


常量池(constant pool)区段

类或接口所定义的常量都会被储存在常量池,包括类名,变量名,接口名称,方法名称及签名,常量值,字符串文字等。常量被作为一个元素长度可变的数组存储在常量池。常量数组大小是可知的,因此,JVM在载入类文件时就知道将有多少常量在常量池。



上图中,用绿色表示的部分就是数组的大小。每一个数组元素第一个字节被用来标记这个常量的类型。上图中橙色表示的部分就是标记字节。虚拟机JVM即通过读取这个字节来识别常量的类型。假如一个字节的标记表示这是一个字符串,那么JVM就知道下面2个字节代表的是字符串长度以及之后的部分即是字符串本身。

 

(译者注:原文对常量池的描述还缺少一个关键内容:常量池计数的值是常量池中元素总数量+1,元素的下标从1开始。例如图中计数为3,那么真正紧跟着计数只有两个元素,下标为1,2。原文的配图多一个元素,在这里改正)


访问标识(access flags)区段

访问标识区段就在常量池区段之后。访问标识区段只有2个字节的数据,用来标识该文件定义的是一个类还是一个接口,是public,abstract还是final的。

This类区段

This类区段也是一个只有2个字节的数据,它的值是常量池中常量数组的一个下标。


 
上图中,This类的值0x0007指向了常量池中的一个常量。那个常量池中相应的条目由两部分组成,第一部分是一个字节的标记,代表了常量池条目的类型,是一个类或是一个接口。由上图中,橙色部分标识的常量条目的类型。后面跟着的两个字节的数据,数据的值又是常量池中的另一个常量值。图中,两个字节的值为0×0004,它指向的是常量池中的接口或类名称的字符串常量。

Super类区段

This类区段之后的2个字节就是Super类区段。结构上和This类很接近,这两个字节的值也是指向常量池里一个下标,而这个常量值后面部分指向的另一个常量值即是指向父类名的字符串。

接口(interfaces)区段

这个类或接口实现的所有接口都定义在了类文件的接口区段。接口区段最开始的2个字节提供了实现的接口的数量信息。紧接着的是一个数组,这个数组中包含着指向常量池中所实现的接口名称的字符串量常下标。

域(fields)区段

域指的是这个类的实例或接口中所定义的变量。每个类文件的域中只包含了这个类或接口内定义的变量,而不包含从父类或父接口中继承的变量。域区段中的前2个字节是一个计数,记录的是这个域中所定义的变量总数。计数之后跟着的是一个数组,数组中每个元素即是一个域变量的定义,变量定义是由长度不同的结构体组成的。有些部分变量的定义是储存在结构体中,还有些部分,如变量名是保存在常量池中的。

方法(methods)区段

方法区段中存放的是这个类或接口中所定义的所有方法,和域一样,这里不包含从父类继承的方法。区段中的头2个字节记录的也同样是这个类或接口定义的方法的数量。其余的部分同样也是一个数组,数组中的每个元素即是一个方法的结构体。每个方法结构体中包含着这个方法中的一些信息,如参数列表,返回类型,方法局部变量所需要的堆栈字数,方法运算栈所需要的堆栈字数,Exception表及字节码序列等。

属性(attributes)区段

属性区段含有这个类文件的一些属性信息,如其中一个属性是源代码属性,用来表示这个类字节码文件的源代码文件名。属性区段的头两个字节是区段中属性的个数,跟着的是属性本身。JVM会忽略掉任何它不识别的属性。

  • 大小: 9.3 KB
  • 大小: 8.2 KB
  • 大小: 8.2 KB
  • 大小: 4 KB
分享到:
评论
2 楼 cgaolei 2009-07-10  
ZangXT 写道
问题:
1.译者注:虽是16进制编码,但实际是英文单词CAFE BABE
其实这就是无符号数,并不是字符。
2.常量池(constant pool)区段
下面的图错误了吧。常量池number为3的话,常量池中只有两项,下表为1和2.
3.Super类区段
和This类很接近,这两个字节的值也是指向常量池里一个下标,指向的常量值即是指向父类名的字符串。
描述很混、存在问题。this_class部分说的很清楚,这个下表指向的是CONSTANT_Class_info类型常量,而指向字符串的部分是在这个CONSTANT_Class_info常量中。


感谢ZangXT的指正:
1. 是我的注释有误导,Magic的值是0xCAFEBABE,我的意思其实是想说这个值16进制的写法正好是英文单词Cafe Babe(咖啡宝贝),以方便记忆。

2. 的确是错的,常量池计数是常量池是项目数加1。图是原文的图,描述中也没有提到这个。我会加上注释更正,但既然是翻译,我应该尽量保留原文描述。

3. 原文中对Super类区段的解释也比较省略,因为有This类区段做参考,两个欧段结构上是相似的,只是指向的内容一个不同。

再次感请ZangXT,我会在正文中做出更正和注释。
1 楼 ZangXT 2009-07-10  
问题:
1.译者注:虽是16进制编码,但实际是英文单词CAFE BABE
其实这就是无符号数,并不是字符。
2.常量池(constant pool)区段
下面的图错误了吧。常量池number为3的话,常量池中只有两项,下表为1和2.
3.Super类区段
和This类很接近,这两个字节的值也是指向常量池里一个下标,指向的常量值即是指向父类名的字符串。
描述很混、存在问题。this_class部分说的很清楚,这个下表指向的是CONSTANT_Class_info类型常量,而指向字符串的部分是在这个CONSTANT_Class_info常量中。

相关推荐

    Java基础教程(快速入门必备)pdf文件

    Java基础教程(快速入门必备)pdf文件

    NetBeans_IDE_Java快速入门教程

    NetBeans_IDE_Java快速入门教程NetBeans_IDE_Java快速入门教程NetBeans_IDE_Java快速入门教程NetBeans_IDE_Java快速入门教程NetBeans_IDE_Java快速入门教程

    java语言快速入门习题与答案

    Java源程序(扩展名为.java)被Java编译器编译成Java字节码文件,这种字节码文件有专门的开发规范要求,它是一种结构独立的中间文件格式,字节码里面并没有保存跟特定平台相关的信息,这就是字节码的平台无关性。...

    JavaWeb 开发快速入门

    主要讲解了一个符合J2ee标准的web工程的组成结构到底是什么样,tomcat的运行机制和原理剖析,javaweb的工作原理及入门知识点

    优质课件 java基础入门必学 Java SE编程入门教程 全套PPT课件 共30个文件 含辅助资料.rar

    Java SE编程入门教程 javaGUI编程快速入门(1)(共82页).pptx Java SE编程入门教程 java包装器(共9页).pptx Java SE编程入门教程 java反射机制(共16页).pptx Java SE编程入门教程 java泛型(共11页).pptx Java ...

    C++转JAVA入门总结

    1. 内置数据类型 2. string类 3. 数组 4. 循环分支 ...6. JAVA流、文件、IO 7. JAVA异常 8. JAVA继承 1. 抽象类与抽象方法 2. JAVA接口 3. JAVA泛型编程 4. JAVA序列化 5.JAVA网络与多线程 6. JAVA类生命周期

    01Java快速入门、IDEA开发工具的使用

    Java快速入门、IDEA开发工具的使用 Java的概述 Java是一门高级编程语言:语言风格接近人类的自然语言,写程序简单易懂 Java的流行度很高,商业占用率很高 很重要的特性:可移植性 Java的技术体系 JavaSE...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让知识环环相扣,降低了学习的难度 通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的每个语法都提供了一个或多个例程讲解 ...

    JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    Micaps 3.0 快速入门手册

    Micaps 3.0 快速入门手册CHM文件

    struts快速入门的最好教程

    Struts2框架简介 Struts2历史 Struts2与MVC Struts2体系介绍 Struts2体系架构 Struts2工作流程 ...默认配置文件struts-default.xml概要说明 Struts2核心配置文件Struts.xml详解 Struts2的简单开发和配置

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让知识环环相扣,降低了学习的难度 通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的每个语法都提供了一个或多个例程讲解 ...

    zero ICE快速入门java版

    zero ICE快速入门文档, ice是最优秀的rpc框架。 4、开发服务端代码如下 步骤一:编写Servant类即带有Disp的存根文件也就是说继承_HelloWorldDisp 这个类,这个类是个抽象类定义如下: public abstract class _...

    java struts2入门学习实例--使用struts2快速实现多个文件上传.doc

    java struts2入门学习实例--使用struts2快速实现多个文件上传

    java入门经典程序

    卡登海德编著的《Java入门经典(第6版)》通过大量示例程序循序渐进地引导读者快速掌握使用Java开发程序的基本技能。《Java入门经典(第6版)》总共24章,先讲解了Java程序的编写流程、工作原理等内容;然后介绍了有关...

    MyEclipse Hibernate 快速入门(电子书)

    4.从 Database Explorer 的表定义中生成 Java 类和 Hibernate 数据库映射文件 (.hbm) 5.使用 HQL 编辑器 6.创建使用 Hibernate 的小测试应用 目录 1.前言 2.准备工作 3.介绍 4.Hibernate 一览 5.创建 ...

    Java从入门到就业全套视频.docx

    文件包含01、JavaWeb阶段 02、Linux 03、Redis 04、JavaWeb综合项目实战 05、Hibernate 06、Struts 07、Spring 08、ssh综合项目实战 09、oracle 10、Maven 11、物流BOS系统 12、mybatis 13、spring mvc 14、SSM综合...

    韩顺平-java从入门到精通视频教程学习笔记(两个版本)-word文件

    压缩包包括两个WORD格式文件: 韩顺平java从入门到精通视频教程(全94讲)学习笔记整理含练习题答案、 韩顺平-java从入门到精通视频教程学习笔记-自习版149页, 供大家学习韩老师视频时参考

    SpringBoot快速入门.zip

    这是一个SpringBoot快速入门的第一个小案例,里面包含了如何在SpringBoot中使用jsp文件,meaven里面的配置大家或许要根据自己数据库的配置进行更改

    JAVA WEB 新手入门笔记

    一、 JavaScript 二、 数据库单表 三、 数据库多表 四、 事务的管理 五、 JDBC ...十四、 文件的上传和下载 十五、 Jquery 十六、 Redis 十七、 nginx & svn 十八、 框架基础加强 十九、 补充

Global site tag (gtag.js) - Google Analytics