我想将一个方法添加到我无法控制的现有类中,例如在Java8的Stream类中有一个方法toList()。问题是这是否可以使用ASM完成。大概吧。
我更具体的问题是我是否可以创建类似于包含扩展方法的jar的东西(比如类Stream)。然后我可以将jar添加到我的项目中,并且在Java8 Stream类中可以看到toList()方法。根据我的理解,扩展方法只能在运行时编织或者我有一个可以执行此操作的运行时(如Groovy,Kotlin,Scala)。我知道有项目Lombok,但它只有一个支持相应功能的eclipse插件。 IntelliJ的插件不支持此特定功能。
答案 0 :(得分:0)
我尝试按顺序回答问题:
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()方法)具有相同的类名,您必须将其加载到另一个classLoader中。例外是使用 Unsafe.defineAnonymousClass(),我认为你不会使用它。