我试图使用反射从超类型引用变量中获取注释细节,以使该方法接受所有子类型。但是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
}
}
如何获取注释信息?
答案 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)
在您的代码中,o1
,o2
和o3
已经是您要呼叫Class<?>
的{{1}}个对象,您不应该之前打电话给isAnnotationPresent(Class<?>)
,因为在这个阶段,您会在getClass()
课程本身打电话给isAnnotationPresent(Class<?>)
,而不是在Class
课程上打电话......