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

是否可以使用ASM向现有Java类添加方法?,java,extension-methods,java-bytecode-asm,Java,Extension Methods,Java Bytecode Asm,我想向我无法控制的现有类添加一个方法,例如,在Java8的流类中有一个方法toList()。问题是,是否可以使用ASM实现这一点。我想是的 我更具体的问题是,我是否可以创建类似于包含扩展方法的jar的东西(比如类流)。然后我可以将jar添加到我的项目中,并且toList()方法在Java8流类中变得可见。据我所知,扩展方法只能在运行时或当我有一个可以这样做的运行时(如Groovy、Kotlin、Scala)时进行编织。我知道有Lombok项目,但它只有一个eclipse插件支持相应的特性。Int

我想向我无法控制的现有类添加一个方法,例如,在Java8的流类中有一个方法toList()。问题是,是否可以使用ASM实现这一点。我想是的


我更具体的问题是,我是否可以创建类似于包含扩展方法的jar的东西(比如类流)。然后我可以将jar添加到我的项目中,并且toList()方法在Java8流类中变得可见。据我所知,扩展方法只能在运行时或当我有一个可以这样做的运行时(如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().
    }
}

问题2:我是否可以创建一个包含扩展方法的jar(比如类流)

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

要添加方法。。。最明显的方法是扩展类,并将该方法添加到childclassYes中,没错。不过,我想要的是一种类似于Groovy、Kotlin、Scala、Smalltalk、C#和其他语言中的扩展方法(对类字符串进行子类化不会有帮助),而不必还原到这些语言中的任何一种。您不能对字符串进行子类化,因为它是一个不可变的类。但是,您可以创建一个正确的复合对象,但问题是关于扩展方法,而不是关于子类化。