Javassist讲解1(介绍,读写字节码)

Javassist讲解1(介绍,读写字节码)


介绍

    javassist 使Java字节码操作变得简单,它是一个用于在Java中编辑字节码的类库;

    它使Java程序能够在运行时定义一个新类,并在JVM加载类文件时对其进行修改

    与其他类似的字节码编辑器不同,javassist提供了两个级别的API:

    源代码级别和字节码级别

    如果用户使用源级API,他们可以在不了解Java字节码规范的情况下编辑类文件。整个API仅使用Java语言的词汇设计,甚至可以以源代码的形式指定插入的字节码,Javassist会即时的进行编译。

    另一方面,字节级API允许用户像其他编辑器一样直接编辑类文件


一、读写字节码

    javassist是一个用于处理Java的字节码的类库。Java字节码存储在成为类文件的二进制文件中。每个类文件都包含一个Java类或接口

java 复制代码
	//获取Class池
	ClassPool pool = ClassPool.getDefault();
	//获取CtClass
	CtClass cc = pool.get("net.mooctest.Yest");
	//修改字节码
	cc.setSuperclass(pool.get("net.mooctest.YestFather"));
	//输出字节码
	cc.writeFile("D:\\桌面\\pair\\PairHeap2\\result1666497514964\\target\\classes");
  • 首先获取一个ClassPool对象,该对象控制使用Javassist修改字节码,ClassPool是一个表示类文件的对象容器
  • ClassPool 是本质一个CtClass 对象的map,使用类名作为键,调用get方法,搜索整个ClassPool,如果没有找到对应的对象,就新构造一个CtClass类对象,该对象被记录在map中,但是注意,这里说得是加载的对象,如果类名对应类不存在,会抛出异常
  • 获取到ClassPool对象后,就可以进行修改,这里的话讲其父类修改为了BaseObj,然后是cc.writeFile(),可以将修改后的字节码进行保存,也可以直接通过toBytecode()获取字节码

最后看到Class文件中可以发现本来没有继承的Yest类成功继承了YestFather类

1.如何创建新的类

  • ClassPool的makeClass方法可以帮助我们定义一个新的不存在的类
  • 但是makeClass()不能创建接口,创建接口需要调用makeInterface方法
java 复制代码
	ClassPool pool = ClassPool.getDefault();
	
	CtClass cc = pool.makeClass("net.mooctest.NewClass");
	
	cc.writeFile("D:\\桌面\\pair\\PairHeap2\\result1666497514964\\target\\classes");

可以看到成功创建了一个NewClass类

2.类冻结

  • 执行了writeFile 或者 toBytecode() 等输出字节码的方法之后,CtClass就处于了冻结的状态,在此状态下不允许修改。
java 复制代码
	ClassPool pool = ClassPool.getDefault();
	
	CtClass cc = pool.makeClass("net.mooctest.Yest");
	
	cc.writeFile("D:\\桌面\\pair\\PairHeap2\\result1666497514964\\target\\classes");
	
	cc.setSuperclass(pool.get("net.mooctest.YestFather"));

	如果在输出之后修改再次修改:
	>>>>>>>>
	Exception in thread "main" java.lang.RuntimeException:
	net.mooctest.Yest class is frozen
  • CtClass 调用 defrost 可以解冻,变为可修改的状态
  • 当 ClassPool.doPruning 属性设置为 true 的时候 ,冻结的类不能再次被解冻
java 复制代码
	ClassPool pool = ClassPool.getDefault();
	
	ClassPool.doPruning = true;

	调用解冻会提示:
	dofrost(): net.mooctest.Yest was pruned
  • doPruning 属性设置为 true ,某一个特定类需要解冻的时候,可以提前调用,这样就不会报错
java 复制代码
	CtClass cc = pool.makeClass("net.mooctest.Yest");
	cc.stopPruning(true);

相关推荐
mldong7 小时前
一个 App,十三套后端:手机审批端 uni-jeeflow-app 开源了
java·架构
tqs_123458 小时前
MySQL RR隔离级别死锁|Gap间隙锁、临键锁,订单并发范围查询死锁根因方案
java
逆境不可逃9 小时前
Pi Agent 学习笔记:多个工具怎样并行执行
java
浪子明X9 小时前
十六位账本怎样发现传输差错:Internet Checksum 生活类比
开发语言
Flynt9 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet9 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
星云API技术支持10 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
niucloud-admin10 小时前
JAVA V6 多商户商城 开发文档——job 计划任务开发
java·python·github
海宇AI11 小时前
零信任架构实战:基于海宇柠檬查出险-登记证构建自动化车抵贷核保网关
java·人工智能·架构·自动化
xiangyun6111 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法