一,前言
注解,在java程序中经常看到的@Override、@Deprecated,在SpringBoot中经常用到的@XX。
注释:书写在代码中用以辅助 人 理解代码的文字,不参与程序的运行,对代码没有任何影响。
注解:①代码中的特殊标记,以“@注释名”的形式存在于代码中,用以辅助程序的理解代码代码,②程序可以读取注解,对被标注的程序(类、方法、属性等)进行限制、规定如何运行等,③也是一种类的类型(自己的理解,不一定完整准确)。
注解在java中的典型应用:通过反射技术获取被注解的代码里的注解,以决定如何运行这段代码,即通过反射机制访问代码。
二,自定义注解
注解也是一种类的类型,开发人员可以自行定义并使用注解。
创建文件时选择Annotation。
以上代码就是一个自定义的注解
- 注解类使用
@interface
关键字进行修饰 - 注解中只能包含属性
- 属性后需要加 ()
- 可以通过使用
default
关键字为属性赋予默认值
三,注解的本质
对注解的class文件进行反编译:
可以看出:
- 注解本身就是接口(interface)
- 注解天生继承了java.lang.annotation.Annotation类
- 注解中的属性变成了接口中的抽象方法
总之,注解本质就是接口
四,注解属性的类型
注解中的属性可以是什么类型的?
从错误提示“only primitive type,String ,Class,annotation,enumeration are permitted or 1-dimensional arrays thereof",注解的属性只能是:
- 基本数据类型
- String
- Class类型
- 枚举类型
- 注解类型
- 以及上面类型中的一位数组
五,使用自定义注解及通过反射获取注解信息
自定义一个注解——>在类中使用——>main函数测试,所以一共需要三个文件
自定义一个注解:
在类中使用:
main函数测试:
但是,此时程序不能运行至正确结果:
此时,在自定义的注解中加入@Retention(RetentionPolicy.RUNTIME)
即可:
这里用到了元注解,将在下文展示。
六,元注解
元注解,用来描述注解的注解,负责注解其他的注解,即对注解的代码进行限制、规定如何运行。
元注解有:@Retention、 @Target、 @Document、 @Inherited(这四个在jDK1.5引入)和@Repeatable(JDK1.8加入)五种
①@Retention
单词本身的意思是保留,该注解用于指定被注解的注解可以保留的域!有三个取值:
- RetentionPolicy.SOURCE:编译时直接丢弃被该注解标注的注解,只在源代码文件中保留;
- RetentionPolicy.CLASS:被该注解标注的注解会被记录在class文件中,运行java程序时JVM不保留;默认值!
- RententionPolicy.RUNTIME:被该注解标注的注解会被记录在class文件中,运行java程序时,JVM会保留被该注解标注的注解,程序可通过反射获取被该注解标注的注解。
所以,新创建的注解的保留域默认是
@Retention(RententionPolicy.CLASS)
,被标注的注解会在程序运行时丢失,,所以此时通过反射获取注解时,程序不能找到注解,所以出现指针为空!——修改保留域@Retention(RententionPolicy.RUNTIME)
即可。
②@Target
指定被@Target修饰的注解能用于修饰哪些程序单元,即指定标注的注解可以修饰的程序类型。
以上代码,通过@Target(ElementType.METHOD)
修饰自定义的注解TestAnnotation,则该注解将只能修饰方法,否则就会报错:
从源码中可以看出,@Target这条注解中只有一个类型是ElementType的数组的属性,其中程序规定了ElementType的可选参数。
也就是说,@Target()在修饰注解时,可以传递固定的几种参数:
- ElementType.TYPE:指定被修饰的注解可注解类或接口
- ElementType.FIELD:指定被修饰的注解可注解域上
- ElementType.METHOD:指定被修饰的注解可注解方法
- ElementType.PARAMETER:指定被修饰的注解可注解参数
- ElementType.CONSTRUCTOR:指定被修饰的注解可注解构造函数
- ElementType.LOCAL_VARIABLE:指定被修饰的注解可注解局部变量
- ElementType.ANNOTATION_TYPE:指定被修饰的注解 可注解 注解类型
- ElementType.PACKAGE:指定被修饰的注解可注解包
- ElementType.TYPE_PARAMETER:表示被修饰的注解能写在类型变量的声明语句中。
- ElementType.TYPE_USE 表示被修饰的注解能写在使用类型的任何语句中
③@Documented
指定被@Documented修饰的注解将被包含在javadoc中;
即,在使用javadoc工具生成文档时,如果某个注解被@Documented修饰,则使用这个注解修饰的程序在API文档中将会包含该注解的说明。
对注解TestAnnotation
使用@Documented
修饰,
使用@TestAnnotation注解修饰程序单元,
则被@TestAnnotation修饰的程序单元在通过javadoc生成文档时,如图
④@Inherited
使用@Inherited修饰某注解a时,被该注解a修饰的类的子类会自动继承注解a
即,@Inherited指定被他修饰的注解将具有继承性——如果某个类使用了@Xxx,则其子类将自动被@Xxx修饰(百度百科)
从上面的源码中的注释可知,注解@Inherited只对类有效,对接口无效。
七,内置注解
java中的已经存在的注解,平时用的也比较多,在此简略总结一下
①@Override
限制重写,仅能用于修饰方法
②@Deprecated
标注过时、危险或废弃的方法、属性或类,被标记的内容一般不推荐使用但可以使用,但在使用时会出现删除线。
③@SuppressWarnings
抑制编辑时的警告信息
以上内容都是基础的总结,学习过后仅能对注解和原理有个大致的认识,但真正在SpringBoot框架中的注解映射等的理解还有待进一步学习。
以上内容是我个人在学习之后的梳理和总结,旨在使所学的内容更加清晰和方面后续复习,故请不勿喷语言表达不清和逻辑结构不清的地方,但虚心接受大家的交流和指导,如果本文能对大家的学习起到帮助,我深感荣幸!