ASM:查找泛型类型的描述符

时间:2016-10-22 04:39:02

标签: java java-bytecode-asm

我正在创建一个基于ASM的实用程序来动态生成类。我需要的一件事是生成一个方法签名,该签名具有泛型类型作为参数。 E.g。

my_print()

问题是如何使用ASM库获取public void setValue(List<String> value) {...} 的描述符。我知道有一种实用方法List<String>,我想知道有asm.Type.getDescriptor(Class)这样的东西,或者我该如何实现呢?

谢谢......绿色

2 个答案:

答案 0 :(得分:3)

您正在寻找签名,而不是描述符。描述符总是引用原始类型。

使用ASM,您通常会使用a SignatureVisitor来实现此目的。对于您的示例,您可以通过以下方式为void : List<String>创建签名:

SignatureVisitor sv = new SignatureWriter();
SignatureVisitor psv = sv.visitParameterType();
psv.visitClassType(Type.getInternalName(List.class));
SignatureVisitor ppsv = psv.visitTypeArgument('=');
ppsv.visitClassType(Type.getInternalName(String.class));
psv.visitEnd();
SignatureVisitor rtv = sv.visitReturnType();
rtv.visitBaseType('V');
String signature = sv.toString();

签名访问者API与其他访问者API一样直观,因为条件要求调用visitEnd但是阅读javadoc可以了解其含义。

答案 1 :(得分:0)

好的只是需要这个的人,这是我的implementation

private static String typeDesc(BeanSpec spec) {
    String root = classDesc(spec.rawType());
    List<java.lang.reflect.Type> typeParams = spec.typeParams();
    if (typeParams.isEmpty()) {
        return root;
    }
    StringBuilder sb = S.builder("<");
    for (java.lang.reflect.Type type : typeParams) {
        BeanSpec specx = BeanSpec.of(type, null, spec.injector());
        sb.append(typeDesc(specx));
    }
    sb.append(">");
    FastStr str = FastStr.of(root);
    str = str.take(str.length() - 1).append(sb.toString()).append(";");
    return str.toString();
}

private static String classDesc(Class c) {
    if (c.isPrimitive()) {
        c = $.wrapperClassOf(c);
    }
    return Type.getDescriptor(c);
}