继续来分析Java字节码,上一节分析了魔数的规则,接下来继续往下分析,其上次总结的规则也一起贴出来:

1、使用javap -verbose命令分析一个字节码文件时,将会分析该字节码文件的魔数、版本号、常量池、类信息、类的构造方法、类中的方法信息、类变量与成员变量等信息。

2、魔数:所有的.class字节码文件的前4个字节都是魔数,魔数值为固定值:0xCAFEBABE。

3、魔数之后的4个字节为版本信息,前两个字节表示minor version(次版本号),后两上字节表示major version(主版本号),所以这里的版本号为“00 00 00 34”,如下:

换算成十进制,表示次版本号为0,主版本号为52,正如咱们用javap -verbose所看到的:

那这个版本信息的值有啥意义呢?其中主版本号52代表JDK1.8,而51表示JDK1.7,往前递减依此类推,所以该文件的版本号为:1.8.0,其中1.8为主版本号,而后面的0为次版本号,怎么来验证这一点呢,当然查看java的版本既可嘛,如下:

我们知道Java是一个向后兼容的语言,对应到字节码上,如果JVM是1.8的, 则它可以正常加载并运行1.8以及1.8jdk所编译出来的字节码文件, 但是反过来则不行。

4、版本号之后的字节则为常量池(constant pool):紧接着主版本号之后的就是常量池入口。一个Java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是Class文件的资源仓库,比如说Java类中定义的方法和变量信息,都是存储在常量池中,常量池中主要存储两类变量:字面量和符号引用。字面量如文本字符串,Java中声明为final的常量值等,而符号引用如类和接口的全局限定名,字段的名称和描述符,方法的名称和描述符等。其中符号引用在之前的复习总结中也有提到过,回顾一下:

【注意】:常量池千万不要理解成它里面只能存不变的常量值,里面也可以有变量相关的信息。

5、常量池的总体结构:Java类所对应的常量池主要由常量池数量与常量池数组这两部分共同构成。常量池数量紧跟在主版本号后面,占据2个字节;常量池数组则紧跟常量池数组之后,常量池数组与一般的数组不同的是,常量池数组中不同的元素的类型、结构都是不同的,长度当然也就不同,但是每一种元素的第一个数据都是一个u1类型,该字节是一个标志位,占据1个字节,JVM在解析常量池时,会根据这个u1类型来获取元素的具体类型。好下面依照该规则来真实查看一下字节码文件:

“常量池数量紧跟在主版本号后面,占据2个字节”,所以我看样一下该字节码文件的常量池数量是?

那咱们来看一下javap -verbose输出的结果来验证一下咱们在字节文件中看到的:

这是因为常量池数组【又叫常量表】中的元素的个数 = 常量池数 - 1(其中0暂时不使用)。 目的是满足某些常量池索引值的数据在特定情况下需要表达【不引用任何一个常量池】的含义;根本原因在于,索引为0也是一个常量(保留常量),只不过它不位于常量表中,这个常量就对应null值;所以常量池的索引从1而非0开始。

好,那具体常量池中的常量都是如何分配的呢,下面需要了解一个图,非常之重要:

可以发现所有常量名都是以CONSTANT开头,以info结尾, 另外下面具体的来说明一下该表怎么来看:

其中第一个tag也就是上面我们描述的“每一个元素的第一个数据都是U1类型”,当它的值为1时,表示是CONSTANT_utf8_info类型的常量,而第二个length为u2类型,占两个字节,表示UTF-8编译的字符串长度,而第三个bytes为u1类型点一个字节,表示长度为length的UTF-8编译的字符串内容,也就是根据length来读多少个字节就刚好将这个常量给读完。好接下来继续往下来看:

拿CONSTANT_Integer_info来说明,第一个tag占一个字节,其值是3,其需要读4个字节的内容则为该Integer常量的值,其它的Floast、Long、Double都类似,就不多说了。

如果tag为7表示类常量,而紧接碰上2个字节表示指向全限定名常量项的索引。

这三个常量稍复杂一点,之后会详细介绍,这里先简单的看一下,也就是对于字段和方法都需要先指定类的,然后再到具体的字段或方法。

反正不晓得讲什么,云里雾里的,没关系,下一次会完完整整的将字节码中的常量池全部按照上表格的描述规则分析一趟,最终会跟用javap -verbose常量池的输出完全对应上,如下:

到那时再回过头来看这张表就会觉得非常之亲切啦~~

Java字节码常量池深入剖析的更多相关文章

  1. Java字节码常量池深度剖析与字节码整体结构分解

    常量池深度剖析: 在上一次[https://www.cnblogs.com/webor2006/p/9416831.html]中已经将常量池分析到了2/3了,接着把剩下的分析完,先回顾一下我们编译的源 ...

  2. Java字节码深度剖析

    Java字节码文件查看 我们有一个类Test01,具体内容如下: package bytecode; public class Test01 { private int i = 0; public i ...

  3. Java字节码文件结构剖析

    今天起开启JVM的新的知识学习篇章----Java的字节码,那学习Java字节码有啥用呢?我们知道Java是跨平台的一门语言,编写一次到处运行,而支撑着这个特性的根基为两点:JVM和.class字节码 ...

  4. 【JVM源码解析】模板解释器解释执行Java字节码指令(上)

    本文由HeapDump性能社区首席讲师鸠摩(马智)授权整理发布 第17章-x86-64寄存器 不同的CPU都能够解释的机器语言的体系称为指令集架构(ISA,Instruction Set Archit ...

  5. JAVA字节码解析

    Java字节码指令 Java 字节码指令及javap 使用说明 ### java字节码指令列表 字节码 助记符 指令含义 0x00 nop 什么都不做 0x01 aconst_null 将null推送 ...

  6. Java字节码操纵框架ASM小试

    本文主要内容: ASM是什么 JVM指令 Java字节码文件 ASM编程模型 ASM示例 参考资料汇总 JVM详细指令 ASM是什么 ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既 ...

  7. Java:从面试题“i++和++i哪个效率高?"开始学习java字节码

    今天看到一道面试题,i++和++i的效率谁高谁低. 面试题的答案是++i要高一点. 我在网上搜了一圈儿,发现很多回答也都是同一个结论. 如果早个几年,我也会认同这个看法,但现在我负责任的说,这个结论是 ...

  8. 打造一个简单的Java字节码反编译器

    简介 本文示范了一种反编译Java字节码的方法,首先通过解析class文件,然后将解析的结果转成java代码.但是本文并没有覆盖所有的class文件的特性和指令,只针对部分规范进行解析. 所有的代码代 ...

  9. 空手套白狼,硬阅java字节码class文件

    如下,是一些java字节码也就是原始的class文件,当应用部署到线上之后,我们能够看到的也就是这样的字样了.那么怎样解呢?就让我们一起,来解读解读字节码吧! Offset A B C D E F C ...

随机推荐

  1. ipad 没有数据线如何上传文件到局域网windows PC 的解决方案

    是的,ios 的封闭性,真麻烦,不想用数据线,还不想用iTunes ,那你找对了. 方案一: (好像只能上传文件,不能下载,能在线查看媒体.) 我的想法是在Windows建立一个http file s ...

  2. 码云clone提示“you do not have permission to pull from the repository”

    使用git进行项目下载,换了电脑,配置了账号和邮箱后,pull一个私有项目的时候,出现如下问题: 原因分析: 由于没有设置Gitee的SSH公钥.生成公钥和配置公钥的办法,可以参考Gitee帮助里面的 ...

  3. 居里先生的猜想 | 皮埃尔·居里诞辰160周年

    皮埃尔·居里(Pierre Curie)先生坐在桌前,手里把玩着一块小磁铁.忽然,一道闪念跃入脑海,他为自己这个大胆的想法激动不已,忍不住伏案疾笔书写起来.不远处,一位安静的青年女子温情脉脉地注视着他 ...

  4. 2019年11月27日 Linux所学知识 总结

    查看网络信息和网络状态 nmcli connection show 使用con-name参数指定公司使用的网络会话名称company,然后依次用ifname参数指定本机的网卡名称. 用autoconn ...

  5. rewrite重写基础实列

    nginx 重写 rewrite 基础及实例 nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不 ...

  6. Django后台缓存运用,提高并发

    图片防盗链 -通过请求头refer控制 -nginx处理 提高网站并发的通用方法 QPS:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准.衡量一个服务器能抗多大并发的重要 ...

  7. 关于verilog实例化的介绍

    概念 当我们完成一个比较完整的系统的时候,通常需要编写一个Testbench来验证自己的设计的功能能否满足设计要求.在这个系统中通常会有一个top模块来连接那些小的模块,verilog通过实例化的方式 ...

  8. Chrome 浏览器光标定位到地址栏

    Windows: Ctrl + L 或 Alt + D Mac: Command + L Linux: Ctrl + L

  9. 用户字符串操作,这里面包括字符串的decode、encode、substract等等操作

    工具类描述:用户字符串操作,这里面包括字符串的decode.encode.substract等等操作 package cn.hgnulb; import java.io.UnsupportedEnco ...

  10. Paypal、Stripe、Braintree,跨境电商金流第三方支付该用哪家?

    在台湾做跨境电子商务生意,电商网站的金流肯定是一个最大的麻烦,Paypal或是Stripe和Braintree则是国际上大家最常用的金流整合第三方支付服务商.这些金流服务大幅简化网站付费过程,都让消费 ...