元注解
注解在注解上面的注解称为元注解。主要有以下五种。
@Retention
表明注解存活时间
@Documented
将注解元素放到Javadoc文档中
@Target
注解可以使用到的地方
在ElementType[]中主要有以下几种类型
TYPE:类型(比如类、注解、枚举)
FIELD:属性
METHOD:方法
PARAMETHOD:方法中的参数
CONSTRUCTOR:构造方法
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解
PACKAGE:包
TYPE_PARAMETER:类型参数
TYPE_USE:类名注解
@Inherited
官方源码:指示批注类型是自动继承的。如果注释类型声明上存在Inherited元注释,并且用户在类声明上查询注释类型,而类声明中没有此类型的注释,则会自动查询类的超类中的注释类型。将重复此过程,直到找到此类型的注释,或者到达类层次结构(Object)的顶部。如果没有任何超类具有此类型的注释,那么查询将指示有问题的类没有此类注释。请注意,如果注释类型用于注释类以外的任何内容,则此元注释类型无效。还要注意,这个元注释只会导致注释从超类继承;已实现接口上的注释没有任何作用。简单的说就是:子类如果只有这个注解 就会去其父类找这个注解 将其他注解继承给子类去使用。
@Repeatable
源码中可以知道这个注解可以被重复多次使用,传的参数是一个Class字节码注解类型。
自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface AnnotationOne {
int id();
String name();
String age() default "18";
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD,ElementType.TYPE})
@Inherited
public @interface AnnotationTwo {
String value() default "";
}
测试类
@AnnotationTwo("testTwo")
public class User {
@AnnotationOne(id = 1, name = "ovo")
public void introduce() {
System.out.println("test users introduce annotationOne");
}
}
测试
public class TestAnnotation {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> userClass = Class.forName("annotation.User");
Annotation[] annotations = userClass.getAnnotations();
for(Annotation annotation : annotations) {
Class<? extends Annotation> type = annotation.annotationType();
System.out.println("类的注解类型" + type); // interface annotation.annotation.AnnotationTwo
System.out.println("包含的实例注解有: " + Arrays.toString(type.getDeclaredFields())); // []
System.out.println("包含的静态注解有: " + Arrays.toString(type.getFields())); // []
System.out.println("注解名称" + type.getName());// annotation.annotation.AnnotationTwo
System.out.println("注解中的方法" + Arrays.toString(type.getDeclaredMethods())); // [public abstract java.lang.String annotation.annotation.AnnotationTwo.value()]
}
// 通过反射获取注解中的方法
Method[] declaredMethods = AnnotationOne.class.getDeclaredMethods();
for(Method method : declaredMethods) {
// public abstract java.lang.String annotation.annotation.AnnotationOne.name()
// public abstract int annotation.annotation.AnnotationOne.id()
// public abstract java.lang.String annotation.annotation.AnnotationOne.age()
System.out.println("注解中的方法有: " + method);
}
// 通过反射获取注解中的属性
Field[] declaredFields = AnnotationOne.class.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println("注解中的属性: " + field); // 无
}
}
}