Подтвердить что ты не робот

Создание методов с общими типами с генератором байт-кода Asm (ClassWriter)

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

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

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

EDIT: выглядит как точка входа "ClassWriter.visitField/Method (...., String signature)). Обратите внимание, что это" описание ", содержащее нормальную информацию об общем классе, но термин" подпись" (в JLS) конкретно относится к генерикам, включая информацию о типе.

4b9b3361

Ответ 1

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

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

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;"

Ответ 2

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