什么是注解
注解 (Annotation),也叫元数据。一种代码级别的说明。它是 JDK1.5 及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
注解的作用
- 能够读懂别人写的代码(尤其是框架相关的代码);
- 实现替代配置文件的功能。比如可能原本需要很多配置文件以及很多逻辑才能实现的内容,如果使用合理的注解,就可以使用一个或多个注解来实现相同的功能。比如spring,dagger等;
- 编译时进行格式检查。
如 @Override 注解放在方法前,如果该方法不是覆盖了某个超类方法,编译的时候编译器就能检查出来。
装逼。 - zhaungbi
注解原理
注解本质是一个继承了 Annotation 的特殊接口,其具体实现类是 Java 运行时生成的动态代理类。而我们通过反射获取注解时,返回的是 Java 运行时生成的动态代理对象 $Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用 AnnotationInvocationHandler 的 invoke 方法。该方法会从 memberValues 这个 Map 中索引出对应的值。而 memberValues 的来源是 Java 常量池。
摘自[注解Annotation实现原理与自定义注解例子](https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html)
元注解
基本的元标签有 @Retention, @Documented, @Target, @Inherited @Repeatable(Java 8加入)。
2.1 @Retention 定义了该注解的生命周期。当 @Retention 应用到一个注解上的时候,作用就是说明这个注解的存活时间。
1. RetentionPolicy.SOURCE: 注解只在源码阶段保留,在编译器完整编译之后,它将被丢弃忽视;
例:@Override, @SuppressWarnings
2. RetentionPolicy.CLASS: 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中;
3. RetentionPolicy.RUNTIME: 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获
取到它们;笔者接触到大部分的注解都是 RUNTIME 的生命周期。
2.2 @Target 表示该注解用于什么地方,可以理解为:当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。可以使用的 ElementType 参数:
- ElementType.CONSTRUCTOR: 对构造方法进行注解;
- ElementType.ANNOTATION_TYPE: 对注解进行注解;
- ElementType.FIELD: 对属性、成员变量、成员对象(包括 enum 实例)进行注解;
- ElementType.LOCAL_VARIABLE: 对局部变量进行注解;
- ElementType.METHOD: 对方法进行注解;
- ElementType.PACKAGE: 对包进行注解;
- ElementType.PARAMETER: 对描述参数进行注解;
- ElementType.TYPE: 对类、接口、枚举进行注解;
2.3 @Documented 是一个简单的标记注解,表示是否将注解信息添加在 Java 文档,即 Javadoc 中。
2.4 @Inherited
Inherited 是指继承,@Inherited 定义了一个注释与子类的关系。如果一个超类带有 @Inherited 注解,那么对于该超类,它的子类如果没有被任何注解应用的话,那么这个子类就继承了超类的注解。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Tuhao {}
@Test
public class Father {}
public class Son extendsFather {}
注解的继承跟Java的继承理解差不多,老爸有的,儿子一定有
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Student {
String value() default "学生";
}
注解属性
注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以无形参的方法形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
自定义注解
自定义注解类编写的规则:
注解类型定义为 @interface,所有的注解会自动继承 java.lang.Annotation 这一接口,而且不能再去继承其他的类或接口;
参数成员只能用 public 或 default 两个关键字修饰;
参数成员只能用基本类型:byte, short, char, int, long, float, double, boolean,以及 String, Enum, Class, Annotations 等数据类型,以及这些类型的数组;
要获取类方法和字段的注解信息,必须通过 Java 的反射技术;
注解也可以不定义成员变量,但这样的注解没有什么卵用;
自定义注解需要使用元注解进行编写;
纸上得来终觉浅,多谢就明白了