字节码是什么?字节码增强有哪些?

分析&回答


什么是字节码?

Java之所以可以“一次编译,到处运行”,一是因为JVM针对各种操作系统、平台都进行了定制,二是因为无论在什么平台,都可以编译生成固定格式的字节码(.class文件)供JVM使用。之所以被称之为字节码,是因为字节码文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取。

image.png

字节码结构

.java文件通过javac编译后将得到一个.class文件,比如编写一个简单的ByteCodeDemo类,如下图的左侧部分:

image.png

示例代码(左侧)及对应的字节码(右侧)编译后生成ByteCodeDemo.class文件,打开后是一堆十六进制数,按字节为单位进行分割后展示如图右侧部分所示。上文提及过,JVM对于字节码是有规范要求的,那么看似杂乱的十六进制符合什么结构呢?JVM规范要求每一个字节码文件都要由十部分按照固定的顺序组成,整体结构如下图所示。

image.png

字节码增强

image.png

字节码增强技术ASM

对于需要手动操纵字节码的需求,可以使用ASM,它可以直接生成.class字节码文件,也可以在类被加载入JVM之前动态修改类行为。

image.png

ASM的应用场景有AOP(Cglib就是基于ASM)、热部署、修改其他jar包中的类等。

反思&扩展


魔数(Magic Number)

所有的.class文件的前四个字节都是魔数,魔数的固定值为:0xCAFEBABE。魔数放在文件开头,JVM可以根据文件的开头来判断这个文件是否可能是一个.class文件,如果是,才会继续进行之后的操作。有趣的是,魔数的固定值是Java之父James Gosling制定的,为CafeBabe(咖啡宝贝),而Java的图标为一杯咖啡。(2) 版本号版本号为魔数之后的4个字节,前两个字节表示次版本号(Minor Version),后两个字节表示主版本号(Major Version)。上图2中版本号为“00 00 00 34”,次版本号转化为十进制为0,主版本号转化为十进制为52,在Oracle官网中查询序号52对应的主版本号为1.8,所以编译该文件的Java版本号为1.8.0。(3) 常量池(Constant Pool)紧接着主版本号之后的字节为常量池入口。常量池中存储两类常量:字面量与符号引用。字面量为代码中声明为Final的常量值,符号引用如类和接口的全局限定名、字段的名称和描述符、方法的名称和描述符。常量池整体上分为两部分:常量池计数器以及常量池数据区,如下图4所示。

image.png


喵呜面试助手: 一站式解决面试问题,你可以搜索微信小程序 [喵呜面试助手] 或关注 [喵呜刷题] -> 面试助手 免费刷题。如有好的面试知识或技巧期待您的共享!

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵呜刷题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值