注解简介
◆ Annotation是从JDK5.0开始引入的新技术.
◆ Annotation的作用:
➢不是程序本身,可以对程序作出解释.(这一点和注释(comment)没什么区别)
➢可以被其他程序(比如:编译器等)读取.
◆Annotation的格式:
➢注解是以"@注释名"
在代码中存在的,还可以添加一些参数值,例如:
@SuppressWarnings(value="unchecked")
.
◆Annotation在哪里使用?
➢可以附加在package , class , method , field
等上面,相当于给他们添加了额外的辅助信息,
我们可以通过反射机制编程实现对这些元数据的访问。
JDK内置注解
➢@Overide
:定义在java.lang.Override
中,此注释只适用于修辞方法+表示一个方法声明打算
重写超类中的另一个方法声明.
➢@Deprecated
:定义在java.lang.Deprecated
中,此注释可以用于修辞方法,属性,类
,表示不
鼓励程序员使用这样的元素[ ,通常是因为它很危险或者存在更好的选择,)
➢@SuppressWarnings
:定义在java.lang.SuppressWarnings
中,用来抑制编译时的警告信息
。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数都是已经定义好了的,
我们选择性的使用就好了:
-
@SuppressWarnings("all")
-
@SuppressWarnings("unchecked")
-
@SuppressWarnings(value={"unchecked","deprecation"})
等等。
元注解
◆ 元注解的作用就是负责注解其他注解
, Java定义了4个标准的meta-annotation
类型,他们被用来
为其他annotation类型提供说明
。
◆ 这些类型和它们所支持的类在java.lang .annotation
包中可以找到.( @Target
, @Retention
,
@Documented
, @Inherited
)
➢@Target
:(用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
➢@Retention
:表示需要在什么级别保存该注释信息,用于描述注解的生命周期
➢ (SOURCE < CLASS < RUNTIME)
➢@Document
:说明该注解将被包含在javadoc中
➢@Inherited
: 说明子类可以继承父类中的该注解
1. @Target
如上所述,用于描述注解的使用范围,表明使用范围时需要在value参数中输入对应的枚举类型,即声明我们的注解可以放置在什么地方,如:
- 1
- 2
- 3
public MyAnnotation { }
此时表示注解可以用于修饰方法,例如:
- 1
- 2
- 3
- 4
- 5
public class Client { <-- public void test() { } }
@Target注解源码:
- 1
- 2
- 3
- 4
- 5
- 6
public Target { ElementType[] value(); }
@Target
所枚举的类型有:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, // 1.8 /** * Type parameter declaration */ TYPE_PARAMETER, /** * Use of a type */ TYPE_USE, // 1.9 /** * Module declaration. */ MODULE }
2. @Retention
@Retention
源码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
public Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }
该注解用于注明该注解可以在什么情况下有效,可填入的参数为RetentionPolicy
的枚举类型,具体有:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
public enum RetentionPolicy { // 源码时有效 SOURCE, // 编译成class文件之后仍有效 CLASS, // 运行时有效 RUNTIME }
遍写自定义注解时一般标RUNTIME
,即运行时有效。
使用:
- 1
- 2
- 3
- 4
public MyAnnotation { }
<--
有效范围:RUNTIME
> CLASS
> SOURCE
其余两个注解比较简单,再次不再赘述。
自定义注解
➢使用@interface
自定义注解时,自动继承了java.lang.annotation.Annotation
接口
➢分析:
-
@ interface
用来声明一个注解, 格式:public @interface 注解名{定义内容}
-
其中的
每一个方法
实际上是声明了一个配置参数
-
方法的名称就是参数的名称
. -
方法前的类型就是参数的类型
(只能是基本类型
,Class
,String
,enum
) -
可以通过
default
来声明参数的默认值 -
如果
只有一个参数成员
,一般参数名为value
-
注解
元素必须要有值
,我们定义注解元素时,经常使用空字符串,0作为默认值
编写一个自定义注解:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
public MyAnnotation { // 注解的参数:参数类型 + 参数名() String name() default ""; int age() default 18; int id() default -1; String[] schools() default {"北京大学","清华大学"}; }
tips: 如果参数没有默认值,则必须给注解对应参数赋值
如果注解的参数名为value
,则可以在赋值时不需要写出参数名,即:
@MyAnnotation(value = "123")
→ @MyAnnotation("123")
其实注解只是为程序提供一些修饰某部分的额外信息,并不能为程序提供直接的作用,即相当于在生产线上为产品标注上一些特定的信息,方便生产线后续的加工和生产。
因此要发挥注解的作用,我们一般需要在运行时使用反射来获取注解所标注的信息,进行一些额外的处理等等。