我正在尝试使用反射从超类型引用变量获取注释细节,以使方法接受所有子类型。但是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
}
}
如何获得注释信息?
您在上调用getClass()
Class<?>
,这将给Class<Class>
。现在Class
本身没有注释,这就是为什么你得到假。我想你需要:
// Note no call to o1.getClass()
Class<?> o1 = SomeEntity.class;
System.out.println(o1.isAnnotationPresent(Table.class));
先看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;
}
}
o1.getClass()
将为您提供类型为java.lang.Class
的对象,该对象没有@Table
注释。我猜你想要o1.isAnnotationPresent(Table.class)
在您的代码中,o1
, o2
和o3
已经是您想要调用isAnnotationPresent(Class<?>)
的Class<?>
对象,您之前不应该在它们上调用getClass()
,因为在此阶段,您将在Class
类本身上调用isAnnotationPresent(Class<?>)
,而不是在SomeEntity
类上…