原理:
    通过反射获取注解时,返回的是Java 运行时生成的动态代理对象$Proxy1,通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler 的invoke方法。该方法会从memberValues 这个Map 中索引出对应的值。而memberValues 的来源是Java 常量池。

    1. @Documented 注解信息是否加在在JavaDoc文档中
    2. @Retention 定义该注解的生命周期(什么时候使用该注解)
    3. RetentionPolicy.SOURCE : 在编译阶段丢弃。在编译结束之后就不再有任何意义,不会写入字节码。@Override, @SuppressWarnings
    4. RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
    5. RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
    6. @Target 注解用于什么地方
    7. ElementType.CONSTRUCTOR: 用于描述构造器
    8. ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
    9. ElementType.LOCAL_VARIABLE: 用于描述局部变量
    10. ElementType.METHOD: 用于描述方法
    11. ElementType.PACKAGE: 用于描述包
    12. ElementType.PARAMETER: 用于描述参数
    13. ElementType.TYPE: 用于描述类、接口(包括注解类型) enum声明
    14. @Inherited 是否允许子类继承该注解