Java注解

内置注解

作用在代码上的注解

注解 作用
@Override 检查该方法是否是重写方法
@Deprecated 标记过时方法
@SuppressWarnings 指示编译器忽略注解中声明的警告

作用在注解上的注解

注解 作用
@Retention 标识这个注解怎么保存,是只存在代码中,还是编入class文件中,或者是在运行时可以通过反射访问
@Documented 标记这个注解是否包含在用户文档中
@Target 标记这个注解应该是哪种Java成员
@Inherited 标记这个注解是继承于哪个注解类

Annotation架构

img
  • 一个Annotation和一个RetentionPolicy关联
  • 一个Annotation和1~n个ElementType关联
  • Annotation有许多实现类

ElementType

ElementType 描述
TYPE 类、接口(包括注释类型)或枚举声明
FIELD 字段声明
METHOD 方法声明
PARAMETER 参数声明
CONSTRUCTOR 构造方法声明
LOCAL_VARIABLE 局部函数声明
ANNOTATION_TYPE 注释类型声明
PACKAGE 包声明

当Annotation与某个ElementType相关联时,就意味着Annotation有了某种用途,例如若一个Annotation对象是METHOD类型,则该Annotation只能用来修饰函数

RetentionPolicy

RetentionPolicy 描述
SOURCE Annotation信息仅存在编译器处理期间,编译器处理完成后就没有该Annotation信息了
CLASS 编译器将Annotation存储于类对应的.class文件中
RUNTIME 编译器将Annotation存储于.class文件中,并可由JVM读入

使用自定义Annotation

@Documented
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String[] value() default "unknown";
}

class Person {
    @MyAnnotation
    @Deprecated
    public void empty() {
        System.out.println("empty");
    }
    
    @MyAnnotation(value={"girl", "boy"})
    public void somebody(String name, int age) {
        System.out.println("somebody: " + name + ", " + age);
    }
}

public class AnnotationTest {
    public static void main(String[] args) throw Exception {
        Person person = new Person();
        Class<Person> c = Person.class;
        Method mSomebody = c.getMethod("somebody", new Class[]{String.class, int.class});
        mSomebody.invoke(person, new Object[]{"lily", 18});
        interatorAnnotations(mSomebody);
        
        // 获取 somebody() 方法的Method实例
        Method mEmpty = c.getMethod("empty", new Class[]{});
        // 执行该方法
        mEmpty.invoke(person, new Object[]{});        
        iteratorAnnotations(mEmpty);
    }
    
    public static void iteratorAnnotations(Method method) {
        // 判断 somebody() 方法是否包含MyAnnotation注解
        if(method.isAnnotationPresent(MyAnnotation.class)){
            // 获取该方法的MyAnnotation注解实例
            MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
            // 获取 myAnnotation的值,并打印出来
            String[] values = myAnnotation.value();
            for (String str:values)
                System.out.printf(str+", ");
            System.out.println();
        }
       
        // 获取方法上的所有注解,并打印出来
        Annotation[] annotations = method.getAnnotations();
        for(Annotation annotation : annotations){
            System.out.println(annotation);
        }
    }
}