注解
一、概述
注解(Annotation)就是代码里的特殊标记,这些标记可以在编译,类加载、运行时被读取,并执行相应的处理。通过 Annotation ,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
Annotation 可以像修饰符一样被使用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明,这些信息被保存在 Annotation 的name=value
对中。
使用示例:
- 生成文档相关的注解
- 在编译时进行格式检查(JDK内置的三个基本注解)
- 跟踪代码依赖性,实现代替配置文件的功能
二、常见注解
| @Override // 编译时校验是不是重写了父类的方法
@Deprecated // 所标注内容,不再被建议使用。
@SuppressWarnings // 抑制编译器警告
|
三、自定义注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | public class AnnotationTest {
public static void main(String[] args) {
}
}
//1. 注解声明为@interface
//2. 内部定义成员,通常使用value表示
//3. 可以指定成员的默认值,使用default定义
//4. 如果自定义注解没有成员,表明是一个标识作用
//5. 如果注解有成员,在使用注解时,需要指明成员的值
// 自定义注解必须配上注解的信息处理流程(使用反射才有意义)
@interface MyAnnotation {
String value() default "hello";
}
@MyAnnotation(value = "Hi")
class Person {
String name;
int age;
}
|
四、元注解
元注解用于修饰其他元注解。JDK5.0
提供了4个标准的元注解。
1. @Documented
用于指定被该元Annotation修饰的Annotation类将被javadoc
工具提取成文档。默认情况下javadoc
是不包括注解的。
2. @Inherited
被它修饰的Annotation将具有继承性。如果某个类使用了被@Inherited
修饰的Annotation,则子类将自动具有该注解。
3. @Retention
指明Annotation的生命周期,使用时必须为该value成员变量指定值。
RetentionPolicy.SOURCE
:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注解
RetentionPolicy.CLASS
:在class文件中有效(即class保留),当运行Java程序时,JVM
不会保留注解,这是默认值。
RetentionPolicy.RUNTIME
:在运行时有效(即运行时保留),当运行Java程序时,JVM
会保留注释,程序可以==通过反射获取==该注释。
4. @Target
用于指定被修饰的Annotation能用于修饰哪些程序元素。
| // 指明SuppressWarnings这个注解只能用在TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE这些类型上。
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
|
五、JDK8
中注解的新特性
1. 可重复注解
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 | import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class AnnotationTest {
public static void main(String[] args) {
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotations {
MyAnnotation[] value();
}
// MyAnnotation上声明Repeatable,成员值为MyAnnotations.class
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String value() default "hello";
}
@MyAnnotation(value = "Hi")
class Person {
String name;
int age;
}
|
2. 类型注解
ElementType.TYPE_PARAMETER
表示该注解能写在类型变量的声明语句中(如:泛型声明)。
ElementType.YTPE_USED
表示该注解能写在使用类型的任何语句中。
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 | import java.lang.annotation.*;
import java.util.ArrayList;
public class AnnotationTest {
public static void main(String[] args) {
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@interface MyAnnotations {
MyAnnotation[] value();
}
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@interface MyAnnotation {
String value() default "hello";
}
class Generic<@MyAnnotation T> {
public void bar() throws @MyAnnotation RuntimeException{
ArrayList<@MyAnnotation String> list = new ArrayList<>();
int num = (@MyAnnotation int) 10;
}
}
|