使用Asm字节码生成器生成具有泛型类型的方法(ClassWriter)

Sta*_*Man 13 java generics code-generation bytecode java-bytecode-asm

使用Asm可以很容易地定义简单的getter和setter(幸运的是,它甚至可以在FAQ中解释).但是有一件事没有提到,而且我一直无法找到文档,那就是如何使用泛型类型信息来实现它们.

我实际上能够很容易地确定泛型类型信息(因为代码将采用现有的字段和/或方法,并且存在完整的泛型类型处理和解析).我只需要为包含泛型类型的类型生成泛型版本.

我希望这就像修改签名的Asm ClassWriter/MethodVisitor调用一样容易,但文档中的一些注释表明它可能不那么容易(因为泛型信息存储在与常规信息不同的位置).

编辑:看起来入口点是"ClassWriter.visitField/Method(....,String signature) - 请注意,它的"描述"包含正常的非泛型类信息,但术语"签名"(在JLS中)具体指的是到泛型 - 包括类型信息.

Ada*_*ter 9

You can build the signature using ASM's SignatureWriter class.

For example, suppose you wish to write the signature for this method:

public <K> void doSomething(K thing)
Run Code Online (Sandbox Code Playgroud)

You could use this code:

SignatureWriter signature = new SignatureWriter();
signature.visitFormalTypeParameter("K");

// Ensure that <K> extends java.lang.Object
{
    SignatureVisitor classBound = signature.visitClassBound();
    classBound.visitClassType(Type.getInternalName(Object.class));
    classBound.visitEnd();
}

// The parameter uses the <K> type variable
signature.visitParameterType().visitTypeVariable("K");

// The return type uses the void primitive ('V')
signature.visitReturnType().visitBaseType('V');

signature.visitEnd();

String signatureString = signature.toString();
Run Code Online (Sandbox Code Playgroud)

Which is equivalent to:

String signatureString = "<K:Ljava/lang/Object;>(TK;)V;"
Run Code Online (Sandbox Code Playgroud)

  • @StaxMan:我也遇到过麻烦。也许这篇文章会有所帮助:[Classworking 工具包:泛型与 ASM](http://www.ibm.com/developerworks/java/library/j-cwt02076.html) (2认同)