Генерация методов с универсальными типами с помощью генератора байт-кода Asm (ClassWriter) - PullRequest
13 голосов
/ 15 июля 2010

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

Я на самом деле могу довольно легко определить информацию об универсальных типах (поскольку код будет принимать существующие поля и / или методы, и существует полная обработка и разрешение универсальных типов). Мне просто нужно сгенерировать универсальную версию для типов, у которых есть универсальный тип.

Я надеюсь, что это так же просто, как и изменение сигнатурных вызовов Asm ClassWriter / MethodVisitor, но некоторые комментарии в документации указывают, что это может быть не так просто (так как общая информация хранится в несколько ином месте, чем обычная информация).

РЕДАКТИРОВАТЬ : выглядит как точка входа "ClassWriter.visitField / Method (...., подпись строки) - обратите внимание, что это" описание ", которое содержит обычную неуниверсальную информацию о классе, но термин «подпись» (в JLS), в частности, относится к обобщенным данным, включая информацию о типе.

Ответы [ 2 ]

9 голосов
/ 29 июля 2010

Вы можете создать подпись, используя класс SignatureWriter ASM.

Например, предположим, что вы хотите написать подпись для этого метода:

public <K> void doSomething(K thing)

Вы можете использовать этот код:

SignatureWriter signature = new SignatureWriter();
signature.visitFormalTypeParameter("K");

// Ensure that <K> extends java.lang.Object
{
    SignatureVisitor classBound = signature.visitClassBound();
    classBound.visitClassType(Type.getInternalName(Object.class));
    classBound.visitEnd();
}

// The parameter uses the <K> type variable
signature.visitParameterType().visitTypeVariable("K");

// The return type uses the void primitive ('V')
signature.visitReturnType().visitBaseType('V');

signature.visitEnd();

String signatureString = signature.toString();

Что эквивалентно:

String signatureString = "<K:Ljava/lang/Object;>(TK;)V;"
0 голосов
/ 26 июля 2010

По моему опыту, большинство библиотек генерации байт-кода на лету не имеют хорошей поддержки универсальных типов;однако стертые классы работают очень хорошо (если, конечно, вы не захотите провести анализ этих классов позже).

...