Как получить доступ к аннотациям типа по параметрам типа получателя
Я смотрю на довольно тривиальный класс с единственным методом, который определяет аннотированный тип получателя:
class Foo<T> {
void foo(Foo<@Bar T> this) {}
}
Теперь я хотел бы получить доступ к аннотации типа для параметра типа получателя @Bar
но API отражения Java возвращает аннотированный необработанный тип при доступе к получателю:
assert Foo.class.getDeclaredMethod("foo")
.getAnnotatedReceiverType()
instanceof AnnotatedParameterizedType;
Утверждение не выполняется, поскольку возвращаемый аннотированный тип возвращается как необработанный тип. Foo
, Это намеренно? Я все еще могу найти @Bar
аннотация при доступе к частным свойствам реализации AnnotatedType
это возвращается.
Я использую последнюю версию Java 8.
3 ответа
Оказывается, это простая ошибка. Сначала я подумал, что это является следствием связанных проблем, но аннотации типов не имеют к этому никакого отношения. Аннотации типов плохо протестированы в текущей реализации среды выполнения Java. Я обнаружил огромное количество проблем, когда углубился в это дело:
- Тип получателя не разрешен как параметризованный тип.
- Типовые аннотации для параметров переменных типа с несколькими типами не фильтруются до их соответствующей границы.
- Невозможно прочитать тип владельца аннотированного параметризованного типа.
- Пример неправильной индексации аннотации типа допустимых границ типа для переменных рекурсивного типа с помощью отражения Java Core.
Это известная ошибка JDK-8058220. Однако проблема глубже, чем может показаться.
Это не может быть легко исправлено без изменений формата файла класса и соответствующих обновлений спецификации. В настоящее время файл класса не содержит информации, необходимой для отличия параметра получателя от обычного (см. JDK-8062582).
Если я запускаю это:
Foo<Integer> f = new Foo<>();
Method m = f.getClass().getDeclaredMethod("foo");
AnnotatedType at = m.getAnnotatedReceiverType();
for (Annotation a:at.getAnnotations()) {
System.out.println("Annotation: "+a);
}
Затем я добавляю аннотацию к типу приемника следующим образом:
public void foo(@Bar(1) Foo<T> this) {}
Теперь вы можете получить доступ к аннотации @Bar(1). Обратите внимание, что я помещаю аннотацию непосредственно в ReceiverParameter, а не в параметр типа, как вы хотите.
Я знаю, что это только частичный ответ прямо сейчас... но я хотел с чего-то начать. Другие могут добавить и дать полный ответ, или я узнаю немного больше с течением времени... Типы приемника и такое использование аннотаций - все это для меня очень ново, и не нужно много документации и примеров.
Я подозреваю, что просто нет доступа к этой информации. Смотрите также ответ на другую тему:
Что касается комментариев, то, что касается получения аннотации из аргумента типа в параметре метода, вышеизложенного нет никакого способа.
В этой же теме показано, как получить доступ к аннотациям для аргументов типа в поле.