Генерация байт-кода Java с общей информацией сигнатуры от refle.Method
Я пытаюсь с помощью байт-кода создать подпись метода из java.lang.reflect.Method. Часть его сигнатуры (универсального типа) является хитрой, поскольку api отражения получить информацию о типе и преобразовать ее в то, что нужно asm, НЕ прост. Знаете какой-нибудь код, который это уже делает?
4 ответа
Я не знаю инструмент, который делает это автоматически. Вероятно, я бы использовал класс org.objectweb.asm.util.ASMifierClassVisitor, чтобы выяснить связь между сигнатурами и вызовами API ASM.
Для класса, содержащего этот код:
public void foo1(Object o1, String s2) {
}
... инструмент сгенерирует:
mv = cw.visitMethod(ACC_PUBLIC, "foo1",
"(Ljava/lang/Object;Ljava/lang/String;)V", null, null);
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 3);
mv.visitEnd();
Для этого кода:
public static final String[] foo2() {
return null;
}
... это сгенерирует:
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL + ACC_STATIC,
"foo2", "()[Ljava/lang/String;", null, null);
mv.visitCode();
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
В FAQ есть примечания по сигнатурам методов, и это поможет вам понять номенклатуру классов Java.
Обратите внимание, что API ASM также можно использовать для превращения java.lang.reflect.Method в org.objectweb.asm.commons.Method. Поскольку вы можете получить класс из java.lang.reflect.Method, вы можете использовать ClassVisitor s / MethodVisitor s для проверки методов.
Я думаю, что пытался сделать что-то очень похожее ( Генерация методов с универсальными типами с помощью генератора байт-кода Asm (ClassWriter)).
Из визитной карточки посетителя класса я вижу этот метод, например:
public List<String> foobar(List<Integer> args, List<Boolean> args2);
будет производить описание как:
(Ljava/util/List;Ljava/util/List;)Ljava/util/List;
(как и ожидалось, без общей информации)
и подпись вроде:
(Ljava/util/List<Ljava/lang/Integer;>;Ljava/util/List<Ljava/lang/Boolean;>;)Ljava/util/List<Ljava/lang/String;>;
(с добавлением дженериков)
поэтому было бы достаточно просто сгенерировать общую подпись для дополнения неуниверсального описания. Это очень похоже на то, как общая информация добавляется в исходный код, за исключением странностей, возникающих при обработке односимвольных примитивных типов.
Я еще не пробовал, но учитывая, что visitMethod() ClassWriter также принимает подпись, я надеюсь, что это будет работать.:)
Я бы предложил использовать существующую библиотеку, например:
Попробуйте использовать библиотеку spring-asm (например, Type.getType(String.class))