注解
- 提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。
**声明注解:**
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {}
一、注解的作用
- 能够读懂别人写的代码(尤其是框架相关的代码);
- 实现替代配置文件的功能。比如可能原本需要很多配置文件以及很多逻辑才能实现的内容,如果使用合理的注解,就可以使用一个或多个注解来实现相同的功能。这样就使得代码更加清晰和整洁;
- 编译时进行格式检查。如 @Override 注解放在方法前,如果该方法不是覆盖了某个超类方法,编译的时候编译器就能检查出来。
二、注解的原理
注解本质是一个继承了 Annotation 的特殊接口,其具体实现类是 Java 运行时生成的动态代理类。
而我们通过反射获取注解时,返回的是 Java 运行时生成的动态代理对象 $Proxy1。
通过代理对象调用自定义注解(接口)的方法,会最终调用 AnnotationInvocationHandler 的 invoke 方法。
该方法会从 memberValues 这个 Map 中索引出对应的值。而 memberValues 的来源是 Java 常量池。
备注:
- 原理涉及的内容比较深入,目前不能理解
三、元注解
- 元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面。
- 或者可以理解为:元注解也是一张标签,但是它是一张特殊的标签,它的作用和目的就是给其他普通的标签进行解释说明的。
四、元注解的种类及说明
- 基本的元标签有 @Retention, @Documented, @Target, @Inherited 四种(后来到了 Java 8 又加入了 @Repeatable)。
1.@Target :规定注解所修饰的对象范围。
ElementType.CONSTRUCTIR; 构造器声明
ElementType.FIELD; 成员变量,对象,属性(包括enum实例)
ElementType.LOCAL_VARIABLE; 局部变量声明
ElementType.METHOD ; 方法声明
ElementType.PACKAGE; 包声明
ElementType.PARAMETER;参数声明
ElementType.TYPE; 类、接口(包括注解类型)或enum声明
2.@Retention : 表示注解的生命周期
RetentionPolicy.SOUREC: 在源文件中有效
RetentionPolicy.CLASS; 在class文件中有效
RetentionPolicy.RUNTIME;在运行时有效
3.@Inherited : 标记注解,主要说明了一种继承性,意思是子类可以继承父类中的该注解(注意:只有当被贴上@Inherited标签的注解被用在类上的时候子类才能获得这个注解)。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}
/**
* 注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。
**/
4.@Documented : 一个简单的标记注解,表示是否将注解信息添加在 Java 文档,即 Javadoc 中。
用于描述其它类型的annotation(注解)应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。(表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。)
5.@Repeatable:Java 8 中加入的,是指可重复的意思。
通常使用 @Repeatable 的时候指注解的值可以同时取多个。
/**
* 一个人既是程序员,又是产品经理,同时也是画家。
**/
@interface Persons {
Person[] value();
}
@Repeatable(Persons.class)
@interface Person {
String role default "";
}
@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan {
...
}
- 上面的代码通过 @Repeatable 定义了 Person,而 @Repeatable 后面括号的类相当于一个容器注解。容器注解就是用来存放其它注解的地方,它本身也是一个注解。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
Class<? extends Annotation> value();
}
上面是 @Repeatable 的源码。按照规定,如果使前面的 Persons 里面可以重复调用某个注解,则 Persons 必须有一个 value 的属性,且属性类型必须为被 @Repeatable 注解的 Person。
更多java基础总结(适合于java基础学习、java面试常规题):
总结篇(9)---字符串及基本类 (1)字符串及基本类之基本数据类型
总结篇(10)---字符串及基本类 (2)字符串及基本类之java中公共方法及操作
总结篇(12)---字符串及基本类 (4)Integer对象
总结篇(14)---JVM(java虚拟机) (1)JVM虚拟机概括
总结篇(15)---JVM(java虚拟机) (2)类加载器
总结篇(16)---JVM(java虚拟机) (3)运行时数据区
总结篇(17)---JVM(java虚拟机) (4)垃圾回收
总结篇(18)---JVM(java虚拟机) (5)垃圾回收算法
总结篇(19)---JVM(java虚拟机) (6)JVM调优
总结篇(24)---Java线程及其相关(2)多线程及其问题
总结篇(25)---Java线程及其相关(3)线程池及其问题
总结篇(26)---Java线程及其相关(4)ThreadLocal
总结篇(27)---Java并发及锁(1)Synchronized
总结篇(31)---JUC工具类(1)CountDownLatch
本文介绍了Java注解的基础知识,包括注解的作用、原理、元注解的种类及使用方法。详细解析了@Target、@Retention、@Inherited、@Documented 和 @Repeatable 的含义与应用场景。
1073

被折叠的 条评论
为什么被折叠?



