Генерация байт-кода Java с общей информацией сигнатуры от рефлекса. Метод - PullRequest
2 голосов
/ 12 июня 2009

Я пытаюсь с помощью байт-кода создать сигнатуру метода из java.lang.reflect.Method. Часть его сигнатуры (универсального типа) довольно сложна, так как api отражения получить информацию о типе и преобразовать ее в то, что нужно asm, НЕ просты. Знаете какой-нибудь код, который это уже делает?

Ответы [ 4 ]

4 голосов
/ 12 июня 2009

Мне не известен инструмент, который делает это автоматически. Вероятно, я бы использовал класс 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();

В часто задаваемых вопросах есть примечания по сигнатурам методов, и это поможет, если вы понимаете Номенклатура классов Java .

Обратите внимание, что API ASM также можно использовать для превращения java.lang.reflect.Method в org.objectweb.asm.commons.Method . Поскольку вы можете получить класс из java.lang.reflect.Method , вы можете использовать ClassVisitor s / MethodVisitor s для проверять методы .

1 голос
/ 15 июля 2010

Я думаю, что пытался сделать что-то очень похожее ( Генерация методов с универсальными типами с помощью генератора байт-кода 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;>;

(с добавлением дженериков)

, поэтому было бы достаточно просто сгенерировать общую подпись для дополнения неуниверсального описания. Это очень похоже на то, как общая информация добавляется в исходный код, за исключением странностей, возникающих при обработке односимвольных примитивных типов.

Я еще не пробовал, но, учитывая, что визит метода ClassWriter () также принимает подпись, я надеюсь, что он будет работать. :)

1 голос
/ 12 июня 2009

Я бы предложил использовать существующую библиотеку, например:

0 голосов
/ 05 июня 2013

Попробуйте использовать библиотеку spring-asm (например, Type.getType (String.class))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...