繁体   English   中英

可以使用ASM向现有Java类添加方法吗?

[英]Possible to add a method to an existing Java class using ASM?

我想将方法​​添加到我无法控制的现有类中,例如在Java8的Stream类中具有方法toList()。 问题是这是否可以使用ASM完成。 大概吧。

我更具体的问题是,是否可以创建包含扩展方法的jar之类的东西(例如Stream类)。 然后,可以将jar添加到我的项目中,并且toList()方法在Java8 Stream类中变为可见。 据我了解,扩展方法只能在运行时或在我可以执行此操作的运行时(例如Groovy,Kotlin,Scala)使用。 我知道有Lombok项目,但是它只有eclipse插件,支持相应功能。 IntelliJ的插件不支持此特定功能。

我尝试按顺序回答问题:

问题1:我想向现有类添加方法,但我无法控制“是”。 无论原始类是什么,都可以向现有类添加新方法/删除现有方法。 ASM的一个简单示例代码是添加

ClassReader cr = new ClassReader(is);//'is' is inputstream to some bytecode.
ClassWriter cw = new SomeClassWriter(ClassWriter.COMPUTE_FRAMES)
cr.accept(cw, 0);

class SomeClassWriter extends ClassVisitor{
    ....
    @Override
    public MethodVisitor visitEnd(){
         MethodVisitor mv = cw.visitMethod(...); 
         toListMethodNode.accept(mv). 
         super.visitEnd().
    }

}

Q2:是否可以创建包含扩展方法的罐子之类的东西(例如对Stream进行分类)

要启用新生成的字节码,您需要通过类加载器加载字节码。 这与是否将其打包为jar无关,如果类加载程序未加载新生成的字节码,则它是无用的。 这里的重点是:普通的类加载器不允许两次加载具有相同符号名的字节码。 因此,新的字节码类(使用toList()方法)具有相同的类名,您必须将其加载到另一个classLoader中。 例外是使用Unsafe.defineAnonymousClass() ,我认为您不会使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM