可以使用ASM将方法添加到现有的Java类中?

我想添加一个方法到我没有控制的现有类,例如在Java8的Stream类中有一个方法toList()。 问题是这是否可以使用ASM来完成。 我猜是这样。

我更具体的问题是,我是否可以创建类似于包含扩展方法的jar(就像类Stream)。 然后我可以将jar添加到我的项目中,并且toList()方法在Java8 Stream类中变得可见。 从我所了解的扩展方法只能在运行时编译,或者当我有一个可以做到这一点的运行时(如Groovy,Kotlin,Scala)。 我知道有龙目岛项目,但它只有一个支持相应功能的eclipse插件。 IntelliJ的插件不支持这个特定的功能。

我尝试按顺序回答问题:

Q1:我想添加一个方法到现有的类,我没有控制是的。 无论原始类是什么,您都可以添加新方法/将现有方法移除到现有类。 一个简单的示例代码与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:是否可以创建类似于包含扩展方法的jar的东西(比如类Stream)

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

Interesting Posts