2016-10-22 5 views
1

Я создаю утилиту на основе ASM для генерации класса на лету. Одной из вещей, которые мне нужны, является создание сигнатуры метода, которая имеет общий тип как параметр. Например.ASM: найти дескриптор родового типа

public void setValue(List<String> value) {...} 

Вопрос заключается в том, как я могу получить дескриптор List<String> используя библиотеку ASM. Я знаю, что есть полезный метод asm.Type.getDescriptor(Class), интересно, есть ли что-нибудь вроде getDescriptor(java.lang.reflect.Type) или как его реализовать?

Спасибо ... Green

+0

Для вашего дескриптора вы просто используете список. Подпись - это то, что вы бы изменили для реализации дженериков. –

ответ

2

Вы ищете подписи, а не дескриптора. Дескриптор всегда ссылается на необработанные типы.

С 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 позволяет изучение последствий.

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); 
}