当与Java中的超类型引用一起使用时,isAnnotationPresent()返回false

时间:2011-09-29 14:40:05

标签: java reflection annotations supertype

我试图使用反射从超类型引用变量中获取注释细节,以使该方法接受所有子类型。但是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 个答案:

答案 0 :(得分:16)

您正在{/ 1}}上调用getClass() Class<?>Class<Class>。现在Class本身没有注释,这就是你弄错的原因。我想你想要:

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

答案 1 :(得分:3)

首先,请参阅java.lang.annotation.Inherited

其次,正如其他人所指出的,您的代码与您的问题略有不同。

第三,回答你的问题..

我遇到过类似的需求很多次,所以我写了一个简短的AnnotationUtil类来完成这个以及其他一些类似的事情。 Spring框架提供了一个类似的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 :(得分:2)

o1.getClass()将为您提供java.lang.Class类型的对象,该对象没有@Table注释。我想你想要o1.isAnnotationPresent(Table.class)

答案 3 :(得分:1)

在您的代码中,o1o2o3已经是您要呼叫Class<?>的{​​{1}}个对象,您不应该之前打电话给isAnnotationPresent(Class<?>),因为在这个阶段,您会在getClass()课程本身打电话给isAnnotationPresent(Class<?>),而不是在Class课程上打电话......