问题
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