2016-08-30 3 views
0

У меня есть аннотация, которая получает «динамический» параметр в соответствии с this idiom, то есть параметр типа интерфейса. Короче говоря:Как создать экземпляр из TypeMirror

public interface MyInterface {} 

public @interface MyAnnotation { 
    Class<? extends MyInterface> value(); 
} 

Теперь, чтобы оценить этот параметр, мне нужно создать экземпляр предоставленной реализации. Ответ, связанный выше, делает это во время выполнения. Тем не менее, я пишу «реальный» (т. Е. Компилятор-время) обработчик аннотации после this tutorial. При работе с типами вы должны учитывать, что они еще не могут быть скомпилированы. Учебник ручки, что (в этом случае, чтобы получить имя типа в) следующим образом:

// Get the full QualifiedTypeName 
try { 
    Class<?> clazz = annotation.type(); 
    qualifiedSuperClassName = clazz.getCanonicalName(); 
    simpleTypeName = clazz.getSimpleName(); 
} catch (MirroredTypeException mte) { 
    DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror(); 
    TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement(); 
    qualifiedSuperClassName = classTypeElement.getQualifiedName().toString(); 
    simpleTypeName = classTypeElement.getSimpleName().toString(); 
} 

Таким образом, чтобы создать экземпляр типа, в try блоке можно использовать newInstance(). Но что мне нужно сделать в блоке catch для создания экземпляра? Или это невозможно, потому что тип еще не скомпилирован? В этом случае, как мне решить проблему «динамического параметра»?

Редактировать: В моем конкретном случае я могу прибегнуть к использованию параметра String и интерпретации его как шаблона Groovy. Все еще ищут ответы.

ответ

2

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

Обратите внимание, что ваше объявление аннотации недействительно. Section 9.6.1 of the Java language specification перечисляет допустимые типы элементов аннотации, а значение пользовательского интерфейса не является одним из них. В лучшем случае, что вы можете получить, это Class<? extends MyInterface>, но тогда у вас есть те же проблемы, что и для его создания.

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

+0

Спасибо за разъяснение. Я исправил промах в моем коде, спасибо за примечание. Исходный код, конечно, правильный. Я соберу новый вопрос и напишу его здесь :) –

+0

Новый вопрос: http://stackoverflow.com/questions/39244034/passing-a-dynamic-parameter-to-an-annotation-that-is-processed- в-компиляции –

0

Был получен ответ Will Lp, который он удалил, поскольку он был связан с Groovy, а не с Java.

Я все же считаю, что это актуально.

При использовании Groovy вы можете фактически pass a closure as a class parameter to an annotation.

Смежные вопросы