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

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

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

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

Править: похож на точку входа, "ClassWriter.visitField/Method (...., Строковая подпись) - отмечают, что это - "описание", которое содержит нормальную неуниверсальную информацию о классе, но термин "подпись" (в JLS) конкретно относится к включающей дженерики информации о типе.

13
задан starblue 30 October 2010 в 17:59
поделиться

2 ответа

Вы можете создать подпись, используя класс 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;"
9
ответ дан 2 December 2019 в 01:41
поделиться

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

-1
ответ дан 2 December 2019 в 01:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: