Java 注解
注解简介
◆ 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参数中输入对应的枚举类型,即声明我们的注解可以放置在什么地方,如:
@Target(value = {ElementType.METHOD})
public @interface MyAnnotation {
}
此时表示注解可以用于修饰方法,例如:
public class Client {
@MyAnnotation <--
public void test() {
}
}
@Target注解源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
@Target
所枚举的类型有:
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
源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
该注解用于注明该注解可以在什么情况下有效,可填入的参数为RetentionPolicy
的枚举类型,具体有:
public enum RetentionPolicy {
// 源码时有效
SOURCE,
// 编译成class文件之后仍有效
CLASS,
// 运行时有效
RUNTIME
}
遍写自定义注解时一般标RUNTIME
,即运行时有效。
使用:
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME) <--
public @interface MyAnnotation {
}
有效范围:RUNTIME
> CLASS
> SOURCE
其余两个注解比较简单,再次不再赘述。
自定义注解
➢使用@interface
自定义注解时,自动继承了java.lang.annotation.Annotation
接口
➢分析:
@ interface
用来声明一个注解, 格式:public @interface 注解名{定义内容}
- 其中的
每一个方法
实际上是声明了一个配置参数
方法的名称就是参数的名称
.方法前的类型就是参数的类型
(只能是基本类型
,Class
,String
,enum
)- 可以通过
default
来声明参数的默认值 - 如果
只有一个参数成员
,一般参数名为value
- 注解
元素必须要有值
,我们定义注解元素时,经常使用空字符串,0作为默认值
编写一个自定义注解:
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
// 注解的参数:参数类型 + 参数名()
String name() default "";
int age() default 18;
int id() default -1;
String[] schools() default {"北京大学","清华大学"};
}
tips: 如果参数没有默认值,则必须给注解对应参数赋值
如果注解的参数名为value
,则可以在赋值时不需要写出参数名,即:
@MyAnnotation(value = "123")
→ @MyAnnotation("123")
其实注解只是为程序提供一些修饰某部分的额外信息,并不能为程序提供直接的作用,即相当于在生产线上为产品标注上一些特定的信息,方便生产线后续的加工和生产。
因此要发挥注解的作用,我们一般需要在运行时使用反射来获取注解所标注的信息,进行一些额外的处理等等。