isAnnotationPresent() return false when used with super type reference in Java

淺唱寂寞╮ 提交于 2020-01-22 14:45:06

问题


I m trying to get the annotation details from super type reference variable using reflection, to make the method accept all sub types. But isAnnotationPresent() returning false. Same with other annotation related methods. If used on the exact type, output is as expected.

I know that annotation info will be available on the Object even I m referring through super type.

@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
    }
}

How to get the annotation info?


回答1:


You're calling getClass() on a Class<?>, which will give Class<Class>. Now Class itself isn't annotated, which is why you're getting false. I think you want:

// Note no call to o1.getClass()
Class<?> o1 = SomeEntity.class;
System.out.println(o1.isAnnotationPresent(Table.class));



回答2:


First, see java.lang.annotation.Inherited.

Second, as others pointed out, your code is a bit different from your question.

Third, to answer your question..

I have encountered a similar need many times so I have written a short AnnotationUtil class to do this and some other similar things. Spring framework offers a similar AnnotationUtils class and I suppose dozen other packages today also contain pretty much this piece of code so you don't have to reinvent the wheel.

Anyway this may help you.

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;
    }
}



回答3:


The o1.getClass() will give you object of type java.lang.Class, which doesn't have @Table annotation. I suppose you wanted o1.isAnnotationPresent(Table.class).




回答4:


In your code, o1, o2 and o3 are already the Class<?> objects on which you'll want to call isAnnotationPresent(Class<?>), you shouldn't call getClass() on them before, because at this stage, you'll call isAnnotationPresent(Class<?>)on the Class class itself, and not on your SomeEntity class...



来源:https://stackoverflow.com/questions/7599006/isannotationpresent-return-false-when-used-with-super-type-reference-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!