Генерация байт-кода 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))

Другие вопросы по тегам