Java字节码生成工具ASM浅析

本文深入探讨了ASM,一个用于操作和生成Java字节码的工具。内容涵盖Class编译形态,包括Complied Class结构、类型和方法描述符、方法体描述,特别是字节码指令。接着介绍了ASM中的关键类,如ClassVisitor、ClassWriter、ClassReader、MethodVisitor和MethodWriter,并展示了如何使用ASM生成和转换类。文章通过实例展示了如何改变类的字节码,添加成员变量和方法,为理解动态代理的底层原理提供了基础。
摘要由CSDN通过智能技术生成

前言

什么是ASM?ASM是一款小巧精致的Java字节码操作工具,可以被用于修改已经存在的类和生成一些还不存在的类。ASM被广泛的应用于OpenJDK、Jacoco、CGLIB等工具。

一、Class编译形态

我们平时在Eclipse里面写的.java文件Eclipse已经帮我们编译好了,实际上编译是有规则的,编译好的类是按照一定规则被编译器生成的,包括类的定义、方法的定义、成员变量的定义规则等等。虚拟机中最后工作的类就是通过ClassLoader把这些编译好的类通过读字节流的形式读取并解析成内存中的可用的类的。

1、Complied Class结构

已编译的类结构如下图,*表示可有可无。实际上这里省略了魔数等虚拟机要求定义的一些成员留下了最关键的类结构信息。


12062369-ea47918e0ede7575.png
已编译类结构

1.1、Complied Class类型和方法描述符

已编译的类中,描述字段和方法都有特定的描述符,所有的类型描述符如下图,对于普通类型每个类型编译之后对应的都是一个大写字母;对于对象类型使用L开头反斜杠做分隔符描述对象;对于数组类型,通过[开头,结合内部使用的类型构成数组的描述。


12062369-3eb6af8f3f3f81aa.png
类型描述符

一个方法被编译之后就会使用方法描述符来描述,小括号里面表示参数类型和参数数量,小括号外面表示返回类型。实际上在已编译类中,返回类型不同的方法也是不同的方法,只不过Java不允许这种方法重载。


12062369-4dd3e99d158ae6b6.png
方法描述符

1.2、Complied Class中的方法体描述

上面的描述符只描述了方法签名,但是一些方法内部的变量,操作都没有描述,要想了解这些我们首先需要了解Java虚拟机模型。
简单来说,Java中每个线程都有自己的栈空间,而方法开始执行的时候会以帧的形式被压入到线程的栈中,方法执行结束(正常返回和抛异常)又从栈中被弹出。描述方法的帧是由局部变量表和操作数栈组成的,前者保存我们定义的int a,int b这种变量,后者保存真正的操作数,如a=1,就保存1。局部变量表中的位置叫做槽位,对于Long和double等长字节类型需要占用两个槽位,其余占用一个槽位。操作数栈中的操作数可以通过字节码指令操作。每个帧被压入线程栈的时候都会被分配该帧私有的操作数栈和局部变量空间,然后由线程在操作数栈通过字节码指令进行相关操作,这就是方法的执行。


12062369-5e6a887932c289d9.png
栈帧结构
1.2.1、字节码指令

字节码指令由操作码和参数组成,字节码指令工作的主要场所就是操作数栈。
常用操作码有两类,一类用于操作变量,另一类用于操作数栈本身

  • 操作变量操作码:ILOAD, LLOAD, FLOAD, DLOAD 和 ALOAD 指令读取一个局部变量,并将它的值压到操
    作数栈中。它们的参数是必须读取的局部变量的索引 i。 ILOAD 用于加载一个 boolean、 byte、char、short 或 int 局部变量。LLOAD、FLOAD 和 DLOAD 分别用于加载 long、float 或 double值。( LLOAD 和 DLOAD 实际加载两个槽 i 和 i+1)。最后, ALOAD 用于加载任意非基元值,即对象和数组引用。与之对应ISTORE、 LSTORE、 FSTORE、 DSTORE 和 ASTORE 指令从操作数栈中弹出一个值,并将它存储在由其索引 i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值