我对 Java 生态系统有点陌生。我正在阅读 ASM 方式(在本文档中https://www.baeldung.com/java-asm)来进行 Java 检测。
而且我不知道ASM什么时候改变字节码,具体来说它是在编译时生效并直接改变类或者在类加载运行时改变代码。
ASM 库根本不负责更改字节码。它是一个用于将字节序列(以类文件格式)转换为另一个字节序列(同样以类文件格式)的工具,尽管您也可以使用它来分析类文件或从头开始生成类文件。
所以你最后得到的是只是一个字节数组。
由于使用此字节数组来有效地更改类是您自己的责任(如果这是您想要的),因此您是决定如何以及何时应用更改的人。
您可以在文件系统中读写类文件,这就像从文件中读写字节一样简单。这些更改将在您下次使用此位置作为类路径或模块路径启动 JVM 时生效。如果已经有一个 JVM 使用此位置运行,则在加载类(如果尚未加载)时,更改可能会生效。
您可以在 defineClass
上使用
MethodHandles.Lookup
将类注入到现有上下文中,如果尚未加载,它将取代现有的类定义
Instrumentation API,它允许安装类文件转换器以按需调用或主动触发转换。 API 允许加载时间转换或更改已加载的类,但允许对已加载的类进行更改是有限的。
重定义可能会改变方法体、常量池和属性(除非明确禁止)。重新定义不得添加、删除或重命名字段或方法,更改方法的签名,更改修饰符或更改继承。重新定义不得更改
NestHost
、NestMembers
、Record
或PermittedSubclasses
属性。