继续来分析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. eclipse界面

    Eclipse工作空间的基本配置 A:行号的显示和隐藏 显示:在代码区域的最左边的空白区域,右键 -- Show Line Numbers即可. 隐藏:把上面的动作再做一次. B:字体大小及颜色 a: ...

  2. 使用django进行大文件的上传下载

    下载 基于Django建立的网站,如果提供文件下载功能,最简单的方式莫过于将静态文件交给Nginx等处理,但有些时候,由于网站本身逻辑,需要通过Django提供下载功能,如页面数据导出功能(下载动态生 ...

  3. Asp.Net Core Identity 完成注册登录

    Identity是Asp.Net Core全新的一个用户管理系统,它是一个完善的全面的庞大的框架,提供的功能有: 创建.查询.更改.删除账户信息 验证和授权 密码重置 双重身份认证 支持扩展登录,如微 ...

  4. 学习笔记:oracle之win10安装卸载oracle 11gR2步骤及常见问题解决

    1.win10下安装oracle11g 1.1 工具原料 oracle11g安装包(64位) 1.2 步骤方法 1.在Oracle官网下载安装包,下载后,得到的文件如图所示: 2.将两个文件进行解压缩 ...

  5. python第五天---集合与format格式化

    """ 集合:set 1.由不同元素组成, 2.无序 3.不可变:数字.字符串.元组 不可变类型 """ s = {1, 2, 3, 4, ...

  6. js — 数组Array

    目录 1. isArray 2. 转换方法 3. 分割字符串 join 4. 栈方法 5. 队列方法 6. 重排序方法 7. 操作方法 8. 位置方法 - 索引 9. 迭代方法 数组 array 解释 ...

  7. shell习题第26题:监控mysql服务

    [题目要求] 假设mysql密码是123456. 写脚本监控mysql服务是否正常,比如是否可以执行show processlist,并检测一下当前的mysql服务是主还是从.如果是从,请判断他的主从 ...

  8. (转)从0移植uboot(三) _编译最小可用uboot

    ref: https://www.cnblogs.com/xiaojiang1025/p/6436752.html 前两篇介绍了uboot-2013.01的配置原理以及大体的运行流程,本文将讨论如何对 ...

  9. css之word-wrap和word-break的区别

    对于英文单词,如果有一个连写且长度很长的英文单词,在第一行显示不下的情况下,浏览器默认不会截断显示,而是把这个单词整体挪到下一行.但是当整体挪到下一行还是显示不完全该肿么办呢?有如下两个方法: wor ...

  10. 【Transact-SQL】统计某字段中的值第一次出现后的2小时内出现的次数

    原文:[Transact-SQL]统计某字段中的值第一次出现后的2小时内出现的次数 table1 name createdate a 2011-03-01 10:00:00 a 2011-03-01 ...