字节码操作有哪些合法用途,人们如何在实践中实现这些基于字节码操作的解决方案?
更新:我应该更清楚地说明这个问题实际上是关于人们使用什么模式和技术来借助字节码操作使他们的代码运行起来。
类似于已经提到的面向方面编程或动态构建代理对象和类似技术。
字节码操作有哪些合法用途,人们如何在实践中实现这些基于字节码操作的解决方案?
更新:我应该更清楚地说明这个问题实际上是关于人们使用什么模式和技术来借助字节码操作使他们的代码运行起来。
类似于已经提到的面向方面编程或动态构建代理对象和类似技术。
字节码操作让您可以实现任意复杂(且有趣)的程序转换,例如:
范围是无穷无尽的;这只是一个小样本。
至于这通常是如何完成的,请从这里开始。
因此,可以读取字节码来实现解释器/JVM。在实现 Java 编译器或另一种以 JVM 为目标的语言(例如Scala和Jython)的编译器时,可以编写/生成字节码。您可能会执行字节码操作来优化字节码(如果您想生产和销售字节码优化器,或者您需要它作为内部工具来让您公司的代码在竞争中具有优势)。同样,您可能会操纵字节码以便在分发之前对其进行混淆。您还可以为面向方面的编程执行字节码操作; 例如,您可能想要插入钩子(可能是出于计时或记录目的或出于其他原因),并且操作字节码比编辑所有源文件更简单或更便宜(例如,如果源代码不可用或来自许多不同的源,并非所有源代码都在一个人的控制之下,或者说服这些团队添加此类钩子可能既昂贵又耗时),这可能是一种情况将修改插入到最终的字节码输出而不是尝试修改原始代码(这可能需要上游或维护单独的分支,或者从仅提供字节码的第三方购买源代码)是有意义的。
有论文Patterns of Aspect-Oriented Design (PDF) 和Aspect-Oriented Design Principles: Lessons from Object-Oriented Design (PDF) 描述了 AOP/字节码操作的一些模式。
就我个人而言,我在一个框架中使用了带有ASM的字节码操作来为使用该框架的类生成一些样板代码。该框架需要客户端代码的自定义 equals() 和 hashCode() 方法,因此我通过挂钩Java 代理来生成这些方法,该代理在 ClassLoader 加载类时修改字节码。我也多次使用CGLIB来生成动态代理(如果这算作 AOP)。
一些框架,如 BEA KODO(Java 数据对象规范的实现)使用字节码操作来“增强”普通旧 Java 对象并基于 XML 描述添加持久性逻辑。
因此,然后在字节码上自动生成数据库映射信息。