如何捕获通用 super class 类型参数的注释?
How to capture annotations on generic super class type arguments?
使用 java 8 可以创建带有目标 ElementType.TYPE_USE 的注释。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE})
public @interface MyAnnotation {
}
此注释可应用于传递给通用超类的类型 class,例如:
public class ClassA extends BaseClass<@MyAnnotation ClassB,@MyAnnotation ClassC>{
...
}
使用下面的代码,我可以轻松地从 ClassA 的实例动态检索超级 class BaseClass 的类型参数列表。
ClassA instanceOfA = new ClassA();
...
Class classOfA = instanceOfA.getClass();
ParameterizedType type = (ParameterizedType)classOfA.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
// types[0] --> ClassB
// types[1] --> ClassC
从那里,我试图找到一种方法来检索每个类型参数的注释,但没有成功。
有没有办法动态地(运行时)检索这些注释?谢谢
编辑:
额外的精度,我想支持以下用例:
public class ClassA extends BaseClass<@Annotation1 ClassB,@Annotation2 ClassC>{
...
}
public class ClassD extends BaseClass<@Annotation3 ClassB,@Annotation4 ClassC>{
...
}
在此示例中,ClassB 在 ClassA 或 ClassD 的上下文中的注释不同(对于 ClassC 也是如此)。
棘手:
import java.lang.reflect.*;
AnnotatedType baseClassAt = classOfA.getAnnotatedSuperclass();
assert (at instanceof AnnotatedParameterizedType);
AnnotatedType[] aTypes = ((AnnotatedParameterizedType)baseClassAt)
.getAnnotatedActualTypeArguments();
assert aTypes.length == 2;
MyAnnotation myAnno0 = aTypes[0].getAnnotation(MyAnnotation.class);
MyAnnotation myAnno1 = aTypes[1].getAnnotation(MyAnnotation.class);
对于 class 级别的注释,我们可以对每个 class 对象使用 getAnnotations()
方法。在您的代码中,我们需要将 Type
类型转换为 Class
并为其获取注释。
例如:
Class classOfA = instanceOfA.getClass();
ParameterizedType type = (ParameterizedType)classOfA.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
for(Type t: types){
System.out.println(t.getTypeName());
Annotation[] ans = ((Class) t).getAnnotations();
for(Annotation an: ans){
System.out.println(an.annotationType());
}
}
下面是一个完整的例子,有两个不同的注释来突出区别:
import java.lang.annotation.*;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class AnnotationChecker {
public static void main(String[] args) {
ClassA instanceOfA = new ClassA();
Class classOfA = instanceOfA.getClass();
ParameterizedType type = (ParameterizedType)classOfA.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
for(Type t: types){
System.out.println(t.getTypeName());
Annotation[] ans = ((Class) t).getAnnotations();
for(Annotation an: ans){
System.out.println(an.annotationType());
}
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation1 {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation2 {
}
class ClassA extends BaseClass<ClassB,ClassC>{
}
class BaseClass<ClassB, ClassC> {
}
@MyAnnotation1
class ClassB {
}
@MyAnnotation2
class ClassC {
}
使用 java 8 可以创建带有目标 ElementType.TYPE_USE 的注释。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE})
public @interface MyAnnotation {
}
此注释可应用于传递给通用超类的类型 class,例如:
public class ClassA extends BaseClass<@MyAnnotation ClassB,@MyAnnotation ClassC>{
...
}
使用下面的代码,我可以轻松地从 ClassA 的实例动态检索超级 class BaseClass 的类型参数列表。
ClassA instanceOfA = new ClassA();
...
Class classOfA = instanceOfA.getClass();
ParameterizedType type = (ParameterizedType)classOfA.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
// types[0] --> ClassB
// types[1] --> ClassC
从那里,我试图找到一种方法来检索每个类型参数的注释,但没有成功。
有没有办法动态地(运行时)检索这些注释?谢谢
编辑: 额外的精度,我想支持以下用例:
public class ClassA extends BaseClass<@Annotation1 ClassB,@Annotation2 ClassC>{
...
}
public class ClassD extends BaseClass<@Annotation3 ClassB,@Annotation4 ClassC>{
...
}
在此示例中,ClassB 在 ClassA 或 ClassD 的上下文中的注释不同(对于 ClassC 也是如此)。
棘手:
import java.lang.reflect.*;
AnnotatedType baseClassAt = classOfA.getAnnotatedSuperclass();
assert (at instanceof AnnotatedParameterizedType);
AnnotatedType[] aTypes = ((AnnotatedParameterizedType)baseClassAt)
.getAnnotatedActualTypeArguments();
assert aTypes.length == 2;
MyAnnotation myAnno0 = aTypes[0].getAnnotation(MyAnnotation.class);
MyAnnotation myAnno1 = aTypes[1].getAnnotation(MyAnnotation.class);
对于 class 级别的注释,我们可以对每个 class 对象使用 getAnnotations()
方法。在您的代码中,我们需要将 Type
类型转换为 Class
并为其获取注释。
例如:
Class classOfA = instanceOfA.getClass();
ParameterizedType type = (ParameterizedType)classOfA.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
for(Type t: types){
System.out.println(t.getTypeName());
Annotation[] ans = ((Class) t).getAnnotations();
for(Annotation an: ans){
System.out.println(an.annotationType());
}
}
下面是一个完整的例子,有两个不同的注释来突出区别:
import java.lang.annotation.*;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class AnnotationChecker {
public static void main(String[] args) {
ClassA instanceOfA = new ClassA();
Class classOfA = instanceOfA.getClass();
ParameterizedType type = (ParameterizedType)classOfA.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
for(Type t: types){
System.out.println(t.getTypeName());
Annotation[] ans = ((Class) t).getAnnotations();
for(Annotation an: ans){
System.out.println(an.annotationType());
}
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation1 {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation2 {
}
class ClassA extends BaseClass<ClassB,ClassC>{
}
class BaseClass<ClassB, ClassC> {
}
@MyAnnotation1
class ClassB {
}
@MyAnnotation2
class ClassC {
}