isAnnotationPresent() return false when used with

2019-03-28 01:56发布

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?

4条回答
成全新的幸福
2楼-- · 2019-03-28 02:42

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...

查看更多
啃猪蹄的小仙女
3楼-- · 2019-03-28 02:48

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;
    }
}
查看更多
\"骚年 ilove
4楼-- · 2019-03-28 02:56

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).

查看更多
The star\"
5楼-- · 2019-03-28 02:58

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));
查看更多
登录 后发表回答