java jpg结构_Java Class 字节码文件结构分析----附带逐字节码分析图

欢迎访问我的博客,同步更新: 枫山别院 今天给大家分享下Java Class字节码文件的结构解析。(文末附有详细大图)

代码

首先我们创建一个Java类,然后添加一些成员变量和方法,如下:

public class Test {

String name = "hello";

int size = 10;

long num = 100;

Double pi = 3.14;

public static void main(String[] args) {

Test test = new Test();

test.print();

}

public void print() {

System.out.print(name);

}

}

大家可以看到,这是一个非常简单的类,仅仅有几个基本类型的成员变量和两个简单的方法。这是为了我们分析Class文件方便起见,没有添加复杂的结构。

编译

然后大家可以用javac命令编译一下这个类。编译之后,我们就得到了一个class文件,用sublime之类的软件打开这个class文件,我们可以看到如下信息:

CA FE BA BE 00 00 00 34 00 40 0A 00 11 00 29 08

00 2A 09 00 0C 00 2B 09 00 0C 00 2C 05 00 00 00

00 00 00 00 64 09 00 0C 00 2D 06 40 09 1E B8 51

..........

00 00 00 0C 00 01 00 00 00 0B 00 1F 00 20 00 00

00 01 00 27 00 00 00 02 00 28

是一行一行的十六进制的字符,每两个字符是一个字节,每个字节之间用空格分隔,我省略掉了中间的多行数据,如果要看完整数据,请看文末。

这些就是编译之后的信息了,文件中的字符在我们看来只是一行一行字符,其实是划分格式的。我们来看一下是如何划分的。

结构

Class文件的结构,是一个结构体,有以下元素,描述如下:

ClassFile {

u4 magic; //魔数

u2 minor_version; //Java的次版本号

u2 major_version; //Java的主版本号

u2 constant_pool_count; //常量池的长度

cp_info constant_pool[constant_pool_count]; //常量池数组

u2 access_flags; //类访问标志

u2 this_class; //类名索引

u2 super_class; //父类名索引

u2 interface_count; //实现的接口的数量

u2 interfaces[interface_count]; //接口数组

u2 fields_count; //字段数量

field_info fields[fields_count]; //字段数组

u2 methods_count; //方法数量

method_info methods[methods_count]; //方法数组

u2 attributes_count; //属性数量

attribute_info attributes[attributes_count]; //属性数组

}

左边u2,u4都是表示字节的长度,u2是两字节,u4是四字节。右边是元素的名称。

Class文件就是由以上元素,一个紧挨一个组成的。总体的结构还是不复杂的,开头的三个值,magic,minor_version,major_version和中间的access_flags,this_class,super_class,他们是固定的位置,固定的字节长度。其他的数量不一定的值,都是一个长度,然后后面就是紧跟着该长度的数组,存储着该组值。数组结构通常都有下一级的子结构。

我把字节文件按照上面的元素格式,以不同的颜色划分了出来,请大家看下结构图:

class-simple.png

看图非常的一目了然,读两遍书,不如看一遍图啊。

连续的相同颜色的格子,是同一种元素的值。元素之间是紧紧的排列在一起,大家可以看到结构非常的紧凑,节省空间。看不清的同学可以下载下来,放大一下看。

分析

1. magic 魔数

我们知道有时候通过后缀识别文件是不准确的,因为很容易就改掉后缀。所以很多文件格式,在文件的开头写上几个固定的值,为了识别方便该种格式。比如PDF文件的开头是“%PDF”,这个固定的值,就叫魔数,其实就是个标识。class文件的魔数就是“CA FE BA BE”,JVM读取开头的四个字节,如果是这个值,那么就认为这个文件是个class。

magic.jpg

2. version 版本号

魔数之后,是版本号,大家可以看到,我们有两部分的版本号。第一个版本号就是次版本号,第二个是主版本号。比如52.0,52是主版本号,0是次版本号。这个版本是为了让JVM识别编译这个clas文件的Java版本,比如Java SE8,对应的版本号是52.0,Java SE7 是51.0,Java SE6 是50.0。如果一个最高只支持Java SE7版本的JVM,读取到一个52.0,那么它可能是执行不了这个class的,以为它是Java SE8编译出来的,可能用了JavaSE8的新特性。

version.jpg

3. constant_pool 常量池

常量池占用了class中非常多的空间,存放着非常多的信息,包括数字,字符串,类和接口的名字,字段和方法的名字等等。上来先是常量池的数量,也就是常量池数组的长度。后面紧跟着就是数组的内容,非常长,结构也不太一样。大家可以仔细看看附录中的详细图,太大了,在这就不截图了。

常量池中元素的子结构虽然有非常多的种类,但是都差不多的。首先是tag,tag的值表示这个元素是一个什么类型,也就是一个什么数据结构,然后JVM就可以根据这个结构来解析数据了。一般的XXX_index就是一个索引,length就是一个长度,bytes中是该元素存储的值。结构非常多,我们后面单独一篇文章介绍下这里。

4. access_flags 类访问标志

access_flags保存的信息是,该类的访问标志,比如是public还是private,是个接口还是个类,或者枚举,等等。

access_flags.jpg

此处 access_flags的值是0x0021,代表什么意思呢?我们需要看个表格:

名称

说明

ACC_PUBLIC

0x0001

public类型

ACC_FINAL

0x0010

final修饰符

ACC_SUPER

0x0020

使用invokespecial字节码指令,在JDK1.2之后添加

ACC_INTERFACE

0x0200

接口

还有好几种类型,我们就先看这些。我们的值是0x0021,好像没有这个值对应的类型。其实是,0x0020 加上 0x0001,也就是说0x0021表示ACC_PUBLIC和ACC_SUPER。也就是说,这是个public访问级别的类。

5. this_class 类名索引

this_class元素保存的是类的全限定类名,即包路径加类名。为什么还有个索引呢?因为这个地方保存的不是具体的全限定类名的字符串,是一个索引值。这个索引是常量池的索引,也就是说,其实真正的全限定类名字符串是在常量池存着呢。我们在附录的详细表中找一下这个值,找到第39行数据的最后,是this_class的位置。

this_class

它的值是0x000c,是十进制的12对吧?我们找常量池中的索引是12的值,在第4行最后。

index_12.jpg

很奇怪,这个地方比不是我们说的全限定类名字符串,是一个叫 name_index的索引。其实这个位置存放的数据,是有一个子结构的,它由tag和 name_index组成。tag的值是7,这个值7代表了一种数据结构,就是 CONSTANT_Class_info,这个类型保存的值是类或者接口的符号引用。又是一个引用,也就是索引。从表上我们可以知道,这个索引的值是49,OK,我们再从常量池找索引49的值。

index_49.jpg

在第26和27行上,我们终于找到了类的全限定名称。

6. super_class 父类名索引

super_class跟this_class是一样的,不过这里保存的是类的父类全限定名称而已。大家可以自己找一下看看。不过需要注意的是,如果没有明确指定某个类的父类,在Java中默认父类都是java.lang.Object,而java.lang.Object本身是没有父类的,所以如果是Object类,它的super_class值就是0。

7. interfaces 接口池

接着就是接口索引表或者说是接口池了,这里保存类实现的接口。

interfaces.jpg

因为我们的类没有实现接口,所以它的长度是0,后面的数组自然也就省略了。

8. fields 字段池

fields.jpg

接着是我们的字段信息。从 fields_count的值我们可以知道有4个字段,这跟我们在代码中的字段数量是一致的。然后紧接着就是字段数组了。字段数组中的元素是有数据结构的。如下:

field_info {

u2 access_flags; //变量的访问标识符

u2 name_index; //名称索引

u2 descriptor_index; //类型信息索引

u2 attributes_count; //自定义属性长度

attribute_info attributes[attributes_count]; //自定义属性池

}

name_index中存的就是字段名字的索引,老规矩大家自己找一下。access_flags是变量的访问标识符,descriptor_index保存的是变量的类型信息。最后剩下的属性,为什么有了类的属性池还会在这里有个字段下的属性池呢?这个字段下的属性池是留给JVM来自定义拓展的,各个JVM实现可能会不一样,JVM遇到识别不了的属性会自动跳过。

9. methods 方法池

大家可以看到,在附录详细大图中,方法池没有展开详细的结构,这是因为这里太复杂了,展开图不太好画,我太懒了,所以没画,哈哈哈哈。依然是上来就是一个长度,3个方法,后面跟着一个数组。有人要问了,不对啊,怎么是3个方法,我们只写了2个。那是因为还有个类的默认构造方法,忘了吧,哈哈。后面有机会我们详细分析方法池的结构。

10. attributes 属性池

属性池这个地方,跟常量池一样,保存了很多信息,不过我们这个类中的属性信息较少。属性也有很多的子结构,而且不同的JVM实现还可能会有自己的属性值,这里我们后面有机会单独说一下,大家现在知道即可。

附录

最后,附上一张非常详细的大图,我在图中画出了更详细的结构,包括常量池中子元素的结构,每个字节对应的值是什么等等,非常详细,也耗费了我很多时间,希望对大家有用。大家可以下载下来,经常看一看。

class.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

泊松分布的分布函数_《可靠性设计》——常用的概率分布

超几何分布:在总数为N、不合格品率为p的一批产品中随机抽取n个样品,且样品中r个不合格品的概率为则称x服从超几何分布。 当N很大时,上式计算相当烦琐,此时可以用二项分布或泊松分布来近似。二项分布:二项分布又称为Ber…

java jvm性能调优_《Java 底层原理》Jvm性能调优

前言Java 的性能调优,主要就是为了防止出现out of memory(oom)。Java出现oom就会直接导致程序停止运行。调优模拟元空间oom的情况importnet.sf.cglib.proxy.Enhancer;importnet.sf.cglib.proxy.MethodInterceptor;importnet.sf.cglib.proxy.MethodProxy;importjava.…

yota3墨水屏设置_汉阳环卫工节前给道路隔音屏“洗澡”

楚天都市报9月27日讯(记者卢成汉 通讯员肖赟 肖利)据了解,三环线汉阳段连接硚口区和经济技术开发区,是货运主通道和入城环路,墨水湖北路二环线延长线高架是二环线汉阳中心城区与三环线的重要连接道,都属“城市快速路”&#xff0c…

java atd_Java字符串String详解

1、String字符串实例化String对象:(1)直接赋值,如:String str"hello";(2)使用关键字 new,如:String strnew String("hello");由图可知:使用 new 的方式在堆内存中开辟了两个空间&#…

while用法_语法宝典:连词while的四种用法,你都学会了吗?

你可能知道while除了表示“当……的时候”,还有它与when, as的用法区别,但是这些还不够全面,今天小编就来给大家详细解析一下相关的用法,一起来看看吧!一、考查表示时间的用法,其意为“当……的时候”。如&…

java基础语法试题_java基础语法测试题

java基础语法测试题 Java 程序设计:07-07考试时间:90 分钟用户:wanggang 难度:0 总分:100导出时间:2011-07-07 13:06:15一、判断题(每题 2 分,总分 20 分)1.( )接口和类一样也可以有继承关系,而…

开发转测试没人要_新人如何快速的进入融入软件测试行业?

古人云“师傅领进门,修行在各人”任何行业的入门门槛都是不一样的,软件测试行业涉及到专业领域的知识,入门的门槛高吗?怎么更好的融入行业呢?首先要说到的是软件测试学习的途径主要就三种,一种自学&#xf…

winform checkbox要点击两次_这个Winform的UI库也太全了!四十多个控件都在这一个项目里了...

之前 Gitee 为大家介绍过几款优质的 Winform 项目:这几个WinForm项目,让你更熟悉 .NET|Gitee 项目推荐,发现Winform在大家心中的地位还是挺高的,那么今天就再给各位分享一款新鲜出炉的 Winform UI库——SunnyUI&#x…

java面向对象结课总结_java面向对象课程总结

前言:从大一下学期接触java面向对象课程,到现在java面向对象课程也是告了一段落,到这一阶段我也学了java的大部分的知识,基本的我大概已经懂了,但是在学习java面向对象这个课程中也积累了很多学习java的经验&#xff0…

苹果ppt_你的PPT太low了,学学苹果吧

人在职场哪能不会PPT,可是辛苦做好的PPT总要换来一句:“好low啊,能不能高大上一点?学学人家苹果员工的工作汇报或者发布会PPT吧!”这个时候你心里肯定要吐槽一句:“天!我要是PPT能做成苹果风&am…

webservice 服务器无法处理请求_Message Queue与WebService比较

最近在使用IBM Websphere Message Queue,与WebService相比,同样是跨平台的通信方式,那么各种有什么优势呢?Message Queue属于比较重量级的应用,在规范化的企业流程中用的比较多。如果企业有很多部门,部门都有自己的系统…

小程序 字号设置 slider滚动改变大小_SteerMouse for mac(鼠标设置工具) v5.4.3

Steermouse Mac版这是一款Mac鼠标设置工具,不论你的Mac OS鼠标是Magic Mouse这样的额蓝牙鼠标还是我们常用的USB鼠标你都可以轻松设置。steermouse mac版软件介绍SteerMouse是一个实用程序,可让您自由地自定义按钮,滚轮和光标速度。无论鼠标是…

JAVA不同类型数组重载_方法的重载;数组 (Java Day05)

一,方法的重载概念:在一个类中,拥有多个方法名相同,参数列表不同的方法的现象叫做方法的重载特征:​ 1、在同一个类中​ 2、方法名相同​ 3、参数列表不同参数列表的不同&#xff1a…

佳博网络打印机改ip工具_换IP软件为什么是网络工作者首选工具?

科技的不断发展也在促使着网络技术的进步,而网络对于我们日常工作生活来说是不可或缺的,太多事情都需要在网络中完成,对于互联网从业者深知其重要性,常常会因为项目的不同需要切换不同的IP地址来进行工作,一般情况下我…

玩ts要注意什么_番禺三维创意拍摄要注意什么

番禺三维创意拍摄要注意什么 广州思卓传媒有限公司(简称思卓传媒)成立于互联网,视频迅速崛起的21世纪,前身为思卓影视工作室,近十年积累了丰富品牌策划制作,以专注,精益求精的匠人精神为追求,致力于产生专业…

java c 客户端_java基于C/S模式实现聊天程序(客户端)

经过这几天对java的学习,用java做了这个计算机网络的课程设计,基于C/S模式的简单聊天程序,此篇文章介绍一些客户端的一些东西。先讲一讲此聊天程序的基本原理,客户端发送消息至服务器,服务器收到消息之后将其转发给连接…

4接口引脚定义_浅谈USB Type-C接口

笔者前段时间做了一款STM32下载器,为了与新时代接轨,在设计电路板的时候首次使用了USBType-C接口,后来发现其确实很好用。就在今天又设计制作了一款USB-hub,在硬件上我又使用了Type-C接口,所以来了兴致,写一…

rocket mq 监听端口_浅谈业务流程中的mq使用方式

假设有个场景:下单成功需要给用户发送消息通知,发送消息通知通过mq实现事务提交前发送mq消息step1:start transactionstep2:生成订单step3:投递消息到mqstep4:commit transaction问题:step3发生…

jsp工程防止外部注入_XPATH注入详解|OWASP Top 10安全风险实践(五)

本文为一些列连载文章之一,不定期更新,计划目录如下:OWASP介绍SQL注入命令注入XML外部实体注入XPATH注入反射式、DOM及存储XSS失效的身份认证和会话管理不安全的直接对象引用安全配置错误敏感信息泄露功能级访问控制缺失跨站请求伪造服务端请…

小程序反编译 g is not defined_培生幼儿启蒙英语 Level B | 小牧羊女在哪?

本栏目为羽佳讲绘本独家专稿,文中图片及音频已获得海豚传媒授权,未经允许请勿转载。大家好!我是毛毛。培生幼儿启蒙英语 Level B(升级版)的分享又来了!想了解这套绘本及购买信息的小伙伴们,可以点击喜大普奔&#xff0…