isAnnotationPresent () возвращает false при использовании со ссылкой на тип super в Java - PullRequest
6 голосов
/ 29 сентября 2011

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

Я знаю, что информация аннотации будет доступна на объекте, даже если я ссылаюсь через супертип.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Table {
    String name();
}
@Table(name = "some_table")
public class SomeEntity {

    public static void main(String[] args) {
        System.out.println(SomeEntity.class.isAnnotationPresent(Table.class)); // true
        System.out.println(new SomeEntity().getClass().isAnnotationPresent(Table.class)); // true

        Class<?> o1 = SomeEntity.class;
        System.out.println(o1.getClass().isAnnotationPresent(Table.class)); // false

        Class<SomeEntity> o2 = SomeEntity.class;
        System.out.println(o2.getClass().isAnnotationPresent(Table.class)); // false

        Object o3 = SomeEntity.class;
        System.out.println(o3.getClass().isAnnotationPresent(Table.class)); // false
    }
}

Как получитьинформация аннотации?

Ответы [ 4 ]

16 голосов
/ 29 сентября 2011

Вы звоните getClass() на a Class<?>, что даст Class<Class>. Теперь Class само по себе не аннотировано , поэтому вы получаете ложь. Я думаю, что вы хотите:

// Note no call to o1.getClass()
Class<?> o1 = SomeEntity.class;
System.out.println(o1.isAnnotationPresent(Table.class));
3 голосов
/ 29 сентября 2011

Сначала см. java.lang.annotation.Inherited.

Во-вторых, как отмечали другие, ваш код немного отличается от вашего вопроса.

В-третьих, чтобы ответить на ваш вопрос ..

Я сталкивался с подобной потребностью много раз, поэтому я написал короткий класс AnnotationUtil, чтобы сделать это и некоторые другие подобные вещи. Spring Framework предлагает аналогичный класс AnnotationUtils, и я полагаю, что дюжина других пакетов сегодня также в значительной степени содержат этот фрагмент кода, поэтому вам не нужно изобретать велосипед.

В любом случае, это может вам помочь.

public static <T extends Annotation> T getAnnotation(Class<?> clazz, Class<T> annotationType) {
    T result = clazz.getAnnotation(annotationType);
    if (result == null) {
        Class<?> superclass = clazz.getSuperclass();
        if (superclass != null) {
            return getAnnotation(superclass, annotationType);
        } else {
            return null;
        }
    } else {
        return result;
    }
}
2 голосов
/ 29 сентября 2011

o1.getClass() даст вам объект типа java.lang.Class, который не имеет @Table аннотации.Я полагаю, вы хотели o1.isAnnotationPresent(Table.class).

1 голос
/ 29 сентября 2011

В вашем коде o1, o2 и o3 уже являются объектами Class<?>, для которых вы хотите вызвать isAnnotationPresent(Class<?>), вы не должны вызывать getClass() для них раньше, потому чтона этом этапе вы будете вызывать isAnnotationPresent(Class<?>) для самого класса Class, а не для своего SomeEntity класса ...

...