public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,//类型注解
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE//类型注解
}
类型注解: JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个: TYPE_PARAMETER和TYPE_USE。
- 在Java8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。
- ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
- ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。
class Generic<@MyAnnotation T>{//注解修饰的结构中没有提到T,其实也是可以通过反射来获取关于T的注解的
//<@MyAnnotation T>这么做之后报错,因为也没有说@MyAnnotation可以修饰T这个结构
}
此时的@MyAnnotation为
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotation {
String value() default "hello";
}
进行修改;
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER})
public @interface MyAnnotation {
String value() default "hello";
}
这样就可以了
注意;
class Generic<@MyAnnotation T> {
public void show() throws @MyAnnotation RuntimeException{
ArrayList<@MyAnnotation String> list = new ArrayList<>();
int num = (@MyAnnotation int) 10L;
}
}
上面的程序中只有<@MyAnnotation T>不报错,其余用注解的地方都报错
解决方法,在MyAnnotation中加TYPE_USE,只要是类型的地方都可以用
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
public @interface MyAnnotation {
String value() default "hello";
}
把注解要做的事通过反射获取,获取功能又封装起来了,更加便捷