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

Java 8: класс для AnnotatedType

В Java 8, Class, похоже, получили методы, чтобы получить представление AnnotatedType его суперклассов и его суперинтерфейсов.

Как вы можете преобразовать Class в свой собственный AnnotatedType? Этот вопрос даже имеет смысл?

Из того, что я могу сказать, AnnotatedType имеет-a Type, а не is-a Type. Это a AnnotatedElement, хотя; все это очень грязно.

Я просматривал Javadocs безрезультатно.

4b9b3361

Ответ 1

Итак, я наконец получил приемлемое понимание интерфейса AnnotatedType. Здесь рабочий пример Java 8 для иллюстрации одного из его применений

public static void main(String[] args) {
    Class<?> fooClass = Foo.class;
    AnnotatedType type = fooClass.getAnnotatedSuperclass();
    System.out.println(type);
    System.out.println(Bar.class == type.getType());
    System.out.println(Arrays.toString(type.getAnnotations()));
    System.out.println(Arrays.toString(type.getDeclaredAnnotations()));
}

public static class Bar {
}

public static class Foo extends @Custom Bar {
}

// So that annotation metadata is available at run time
@Retention(RetentionPolicy.RUNTIME)
// TYPE_USE being the important one
@Target(value = {ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE,
        METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE}) 
public @interface Custom {
}

Отпечатает

su[email protected]1d44bcfa
true
[@com.testing.Test$Custom()]
[@com.testing.Test$Custom()]

Интерфейс AnnotatedType

AnnotatedType представляет собой потенциально аннотированное использование типа в программа, запущенная в настоящее время на этой виртуальной машине.

и Class#getAnnotatedSuperclass() состояния javadoc

Возвращает объект AnnotatedType, который представляет использование типа для укажите суперкласс объекта, представленного этим объектом Class.

Я сделал потенциально жирным шрифтом в AnnotatedType javadoc, потому что он дает понять, что использование типа не нужно аннотировать. Если у вас

public static class Bar {}
...
Bar.class.getAnnotatedSuperclass(); // returns Class instance for java.lang.Object

Это пример использования, который не был возможен в Java 7 и ниже, потому что вы не могли аннотировать типы использования (см. примеры здесь). Однако в Java 8 вы можете сделать

public static class Foo extends @Custom Bar {

где тип Bar используется как суперкласс, и его использование аннотируется с помощью @Custom. Следовательно, это AnnotatedType. Поэтому Foo.class.getAnnotatedSuperClass() вернет экземпляр AnnotatedType для этого использования.

Как вы можете преобразовать Class в свой собственный AnnotatedType? Это вопрос даже имеет смысл?

Вопрос не имеет смысла. Это связано с тем, что объект Class содержит автономные метаданные о классе. Я имею в виду все, что может быть выведено из файла класса .class (или фактического объявления). Вы не можете выводить какие-либо виды использования в другом месте, и поэтому он не может быть преобразован в любой AnnotatedType для себя.

У вас может быть

public static class Foo extends @Custom Bar {}

public static class Zoom extends @Custom Bar {}

public static class Doing extends @Custom Bar {}

Существует экземпляр AnnotatedType для каждого из указанных выше способов использования Bar, но какой из них вы бы выбрали для преобразования [Bar] Class в свой собственный AnnotatedType?

Ответ 2

Вот простой пример, показывающий использование getAnnotatedSuperclass():

import java.lang.annotation.*;

public class AnnotationTest {

    @Target(ElementType.TYPE_USE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface First { }

    @Target(ElementType.TYPE_USE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface Second { }

    class A { }

    class B extends @First @Second A { }

    public static void main(String[] args) {
        Annotation[] anns = B.class.getAnnotatedSuperclass().getAnnotations();
        System.out.printf("There are %d annotations on B use of its superclass.%n", anns.length);
        for (Annotation a : anns)
            System.out.println(a.annotationType().getName());
    }
}

Выход из этой программы:

There are 2 annotations on B use of its superclass.
AnnotationTest$First
AnnotationTest$Second

Обратите внимание на различие аннотаций, встречающихся в использовании суперкласса B (а именно A), в отличие от объявления самого A.