不定期更新中……
元注解
@Documented
仅用在注解类上,表示在使用 javadoc 工具生成帮助文档时,使用该注解的类会在 API 文档中展示该注解。
注解版本:1.5+
场景举例:
创建一个注解类 TestAnnotation
1
2
3
4
5
6
7
8
9
10
11
12package com.xs.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
public TestAnnotation {
public String value() default "javadoc";
}创建一个使用该注解的类 DocumentTest
1
2
3
4
5package com.xs.annotation;
public class DocumentedTest {
}生成 javadoc(使用 javadoc 命令 或 使用 eclipse、IDEA 等 IDE 提供的 javadoc 生成工具)
打开生成的 API 文档(/doc/index.html),如下:
若删除注解类 TestAnnotation 中的 @Documented 注解,再次生成 javadoc,注解消失。
@Inherited
仅用在注解类上,被它修饰的注解具有继承性。也就是说,在一个类上使用被 @Inherited 标注的注解,其子类也会继承这些被 @Inherited 标注的注解。
注解版本:1.5+
场景举例:
创建一个带有 @Inherited 的注解类 InheritedAnnotation
1
2
3
4
5
6
7
8
9
10
11
12
13package com.xs.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
public InheritedAnnotation {
public String value() default "Inherited";
}创建一个使用该注解的类 InheritedParent
1
2
3
4
5
6
7
8package com.xs.annotation;
import com.xs.annotation.TestInheritedAnnotation;
public class InheritedParent {
}为 InheritedParent 类创建子类 InheritedChild
1
2
3
4
5
6
7
8
9
10
11
12package com.xs.annotation;
import com.xs.annotation.InheritedParent;
public class InheritedChild extends InheritedParent {
public static void main(String[] args) {
Class<InheritedChild> child = InheritedChild.class;
InheritedAnnotation annotation = child.getAnnotation(InheritedAnnotation.class);
System.out.println(annotation.value());
}
}运行 main 方法,输出如下。
1
parent
@Retention
仅用在注解类上,用来描述注解保留的时间范围。一共有三种策略,定义在 RetentionPolicy 枚举中,分别是:源文件保留、编译期保留、运行期保留,默认值为编译期保留。运行期保留可以用来获取注解信息。
注解版本:1.5+
场景举例:
分别实现三种策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.xs.annotation.meta;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public SourcePolicy {
}
public ClassPolicy {
}
public RuntimePolicy {
}创建一个类,并使用以上三种注解去注解三个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package com.xs.annotation.meta;
public class RetentionTest {
public void sourcePolicy() {
}
public void classPolicy() {
}
public void runtimePolicy() {
}
}生成字节码文件
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90javap -verbose RetentionClass
## 以下为输出结果 ###
警告: 二进制文件RetentionClass包含com.xs.annotation.meta.RetentionClass
Classfile /Users/lihuiming/git/xs/xs-technology/xs-learning-annotation/target/classes/com/xs/annotation/meta/RetentionClass.class
Last modified 2021-2-20; size 709 bytes
MD5 checksum 88516f888e7e83d00ffe708e32d852a0
Compiled from "RetentionClass.java"
public class com.xs.annotation.meta.RetentionClass
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
1 = Methodref #3.#20 // java/lang/Object."<init>":()V
2 = Class #21 // com/xs/annotation/meta/RetentionClass
3 = Class #22 // java/lang/Object
4 = Utf8 <init>
5 = Utf8 ()V
6 = Utf8 Code
7 = Utf8 LineNumberTable
8 = Utf8 LocalVariableTable
9 = Utf8 this
10 = Utf8 Lcom/xs/annotation/meta/RetentionClass;
11 = Utf8 sourcePolicy
12 = Utf8 classPolicy
13 = Utf8 RuntimeInvisibleAnnotations
14 = Utf8 Lcom/xs/annotation/meta/RetentionClassPolicy;
15 = Utf8 runtimePolicy
16 = Utf8 RuntimeVisibleAnnotations
17 = Utf8 Lcom/xs/annotation/meta/RetentionRuntimePolicy;
18 = Utf8 SourceFile
19 = Utf8 RetentionClass.java
20 = NameAndType #4:#5 // "<init>":()V
21 = Utf8 com/xs/annotation/meta/RetentionClass
22 = Utf8 java/lang/Object
{
public com.xs.annotation.meta.RetentionClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 8: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/xs/annotation/meta/RetentionClass;
public void sourcePolicy();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 12: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lcom/xs/annotation/meta/RetentionClass;
public void classPolicy();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 16: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lcom/xs/annotation/meta/RetentionClass;
RuntimeInvisibleAnnotations:
0: #14()
public void runtimePolicy();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 20: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lcom/xs/annotation/meta/RetentionClass;
RuntimeVisibleAnnotations:
0: #17()
}
SourceFile: "RetentionClass.java"从字节码可以看出,编译器没有记录下 sourcePolicy() 方法的注解信息,分别使用了 RuntimeInvisibleAnnotations 和 RuntimeVisibleAnnotations 属性去记录了classPolicy()方法 和 runtimePolicy()方法 的注解信息。
@Target
仅用在注解类上,用来标注注解的元素类型(ElementType),即设置注解的适用范围。如果没有标注 @Target,那么该注解可以作用在任何地方。
注解版本:1.5+
场景举例:
1 | package javax.validation; |
常用注解
@Deprecated
标注在类、接口、成员方法和成员变量上,表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。
注解版本:1.5+
场景举例:
1 |
|
@FunctionalInterface
Java 8 版本后,Java引入函数式编程。@FunctionalInterface 就是 Java 8 版本新增的注解,用来标注函数式接口。
什么是函数式接口?如果接口中只有一个抽象方法(可以包含多个默认方法或多个 static 方法),那么该接口就是函数式接口。函数式接口是为 Java 8 的 Lambda 表达式准备的。
@FunctionalInterface 本身只起到标注作用,用来告诉编译器检查这个接口是否符合函数式接口的规范(只能包含一个抽象方法)。
注解版本:1.8+
场景举例:
1 | package org.springframework.boot; |
@Override
标注在方法上,用来标注方法为重写方法。
注解版本:1.5+
场景举例:
1 | public class Parent { |
@PostConstruct
@PostConstruct 该注解被用来修饰一个非静态的 void() 方法。被 @PostConstruct 修饰的方法会在服务器加载 Servlet 的时候运行,并且只会被服务器执行一次。PostConstruct 在构造函数之后执行,init() 方法之前执行。
该注解的方法在 Spring 整个 Bean 初始化中的执行顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)。
注解版本:Common Annotations 1.0+
场景举例:
1 | public class Test { |
@PreDestroy
注解版本:Common Annotations 1.0+
场景举例:
@Qualifier
注解版本:
场景举例:
@SafeVarargs
标注在 static 或 final 方法上,表示被该注解修饰的方法取消显示指定的编译器警告。
注解版本:1.7+
场景举例:
1 | public class SafeVarargsClass { |
@Scope
注解版本:
场景举例:
@Singleton
注解版本:
场景举例:
@SuppressWarnings
标注在类或方法上,表示被该注解修饰的程序元素(以及该程序元素中的所有子元素)取消显示指定的编译器警告,且会一直作用于该程序元素的所有子元素。
注解的使用有以下三种:
抑制单类型的警告:@SuppressWarnings(“unchecked”)
抑制多类型的警告:@SuppressWarnings(“unchecked”,”rawtypes”)
抑制所有类型的警告:@SuppressWarnings(“unchecked”)
全部关键字请参考附录:[@SuppressWarnings 关键字](#@SuppressWarnings 关键字)
注解版本:1.5+
场景举例:
1 |
|
附录
ElementType
The constants of this enumerated type provide a simple classification of the syntactic locations where annotations may appear in a Java program. These constants are used in {@link Target java.lang.annotation.Target} meta-annotations to specify where it is legal to write annotations of a given type.
版本:1.5+
取值 | 释义 |
---|---|
TYPE | 用于描述类、接口(包括注解类型)、枚举 |
FIELD | 用于描述字段(包括枚举、常量) |
METHOD | 用于描述方法 |
PARAMETER | 用于描述形参 |
CONSTRUCTOR | 用于描述构造器 |
LOCAL_VARIABLE | 用于描述局部变量 |
ANNOTATION_TYPE | 用于描述注解类型 |
PACKAGE | 用于描述包 |
TYPE_PARAMETER | JAVA 8 新增,作用在泛型上 |
TYPE_USE | JAVA 8 新增,用于描述任何类型 |
RetentionPolicy
Annotation retention policy. The constants of this enumerated type describe the various policies for retaining annotations. They are used in conjunction with the {@link Retention} meta-annotation type to specify how long annotations are to be retained.
版本:1.5+
取值 | 释义 |
---|---|
SOURCE | 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃; |
CLASS | 注解被保留到 class文件,但jvm加载class文件时候被遗弃,默认为该级别; |
RUNTIME | 注解不仅被保存到 class文件中,jvm加载class文件之后,仍然存在; |
@SuppressWarnings 关键字
关键字 | 用途 |
---|---|
all | 抑制所有警告 |
boxing | 抑制装箱、拆箱操作时候的警告 |
cast | 抑制映射相关的警告 |
dep-ann | 抑制启用注释的警告 |
deprecation | 抑制过期方法警告 |
fallthrough | 抑制在 switch 中缺失 breaks 的警告 |
finally | 抑制 finally 模块没有返回的警告 |
hiding | 抑制相对于隐藏变量的局部变量的警告 |
incomplete-switch | 忽略不完整的 switch 语句 |
nls | 忽略非 nls 格式的字符 |
null | 忽略对 null 的操作 |
rawtypes | 使用 generics 时忽略没有指定相应的类型 |
restriction | 抑制禁止使用劝阻或禁止引用的警告 |
serial | 忽略在 serializable 类中没有声明 serialVersionUID 变量 |
static-access | 抑制不正确的静态访问方式警告 |
synthetic-access | 抑制子类没有按最优方法访问内部类的警告 |
unchecked | 抑制没有进行类型检查操作的警告 |
unqualified-field-access | 抑制没有权限访问的域的警告 |
unused | 抑制没被使用过的代码的警告 |