无外部库的Java字节码操作

无外部库的Java字节码操作,java,bytecode-manipulation,Java,Bytecode Manipulation,ASM、BCEL、Javaassist和AspectJ等库都能够进行运行时字节码操作,但它们是如何实现的呢 我以前使用ASM做过一些基本的字节码操作,但我不明白它是如何工作的。Java代理是否在程序的其余部分之前在JVM中执行,从而允许ASM在JVM执行编译的类之前加载并编辑它们 如果是这样,是否可以执行java字节码操作,而无需使用外部库(如ASM)、使用BufferedReader加载编译的类文件以及编写自定义解析器等。例如?类文件只是一个字节序列,其格式在中指定BufferedReader

ASM、BCEL、Javaassist和AspectJ等库都能够进行运行时字节码操作,但它们是如何实现的呢

我以前使用ASM做过一些基本的字节码操作,但我不明白它是如何工作的。Java代理是否在程序的其余部分之前在JVM中执行,从而允许ASM在JVM执行编译的类之前加载并编辑它们


如果是这样,是否可以执行java字节码操作,而无需使用外部库(如ASM)、使用BufferedReader加载编译的类文件以及编写自定义解析器等。例如?

类文件只是一个字节序列,其格式在中指定
BufferedReader
用于文本文件,因此您可能需要
BufferedInputStream
,但格式相当复杂


您可以加载被操纵的类文件,就像它们是由
javac
生成的一样。您还可以使用
java.net.URLClassLoader.newInstance
或类似工具动态加载它们。Java Agent允许在加载类文件时通过Java或本机接口修改类文件(如果您想在加载类之前修改类,则必须使用本机接口)。

这些库基于标准Java API,当然,您也可以在没有这些库的情况下使用这些库

首先,Java类文件只是定义良好格式的字节序列,如中所述。上述库的主要任务是提供处理这种格式字节序列的工具。第二个是获取现有类的定义,或者导出修改过的或新创建的类

处理第二项任务有两种不同的方法。一种是从持久性存储(如文件系统或jar文件等)中读取编译后的类,并在特定代码未运行时将它们写回这些存储,就像构建和部署工具那样。这应该很简单,因为它可以归结为读取和写入字节

另一个是在运行时操纵类,Java代理可以通过。它提供了在类首次使用之前的加载/定义时截取类的机制,还提供了重新定义类的机制。后者不能自由更改它们,目前,它必须保留所有字段和方法声明,因此它主要用于更改方法的可执行代码

如果您想要在没有其他第三方库的情况下处理类文件的示例,可以在Stackoverflow上找到一些答案


当然,这些示例只是单一用途的代码或草图。如果您将它们扩展到更一般或更有用的内容,您很快就会基本上重新实现这些库。

术语“外部库”可能有点模糊。不管“外部库”在做什么,理论上你总是可以复制粘贴它们的代码,然后它们就不再是“外部的”。似乎问题在于这些库如何真正实现它们正在做的事情。(我现在可以再次参考他们的源代码,但是……也许有人可以写一个正确的答案……)我想第三方库会是一个更好的表达方式,尽管我将研究上述库的源代码,但是任何评论仍然很感谢感谢您的深入回复,我已经有了一个相当相似的理解,但我感谢澄清和例子