【笔记】Java的注解

前言

Java的注解学习笔记
JDK1.5以后的新特性

注解的功能

  • 编写文档,通过代码里标识的注解生成文档
  • 编译检查,通过代码里标识的注解让编译器能够实现基本的编译检查
  • 代码分析,通过代码里标识的注解对代码进行分析

注解的分类

  • 源码注解
  • 编译注解
  • 运行时注解

JDK内置注解

@Override

  • 检查该方法是否为父类方法的重写方法

@Deprecated

  • 表示该方法已过时,不推荐使用,但仍能正常使用功能

@SuppressWarnings

  • 屏蔽警告

屏蔽所有警告

1
@SuppressWarnings("all")

元注解

  • 是定义注解的注解

@Target:定义注解的使用范围

ElementType.TYPE:作用于类上
ElementType.METHOD:作用于方法上
ElementType.FIELD:作用于属性上

@Retention:定义注解的生命周期

RetentionPolicy.SOURCE:定义这是一个源码注解
RetentionPolicy.CLASS:定义这是一个编译注解
RetentionPolicy.RUNTIME:定义这是一个运行时注解

@Documented:动态生成文档
@Inherited:是否允许子注解继承注解

通过@Documented生成API文档

<name>:类名

1
javadoc <name>.java

自定义注解

  • 自定义注解需要借助元注解来定义注解
  • 如果需要默认值,需要在定义注解属性时通过default关键字定义默认值

<name>:注解名

1
2
3
4
5
6
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface 注解名 {
String 属性名();
String 属性名() default 默认值;
}

默认属性

1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface 注解名 {

}
  • 如果注解中没有定义任何属性,那么仍然存在一个默认属性value(),它的默认值为空
1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface 注解名 {
String value() default "";
}

注解的属性

使用注解的默认值

  • 如果使用注解的时候,为注解的属性赋值时,没有指定属性值,则使用默认值
1
2
3
4
@注解名(属性名 = 属性值)
class 类名 {
...
}

默认属性

  • 如果使用注解的时候,为注解的属性赋值时,没有指定属性名,则默认为value()属性赋值
1
2
3
4
@注解名("属性值")
class 类名 {
...
}

其他注解

1
2
3
4
@注解名(属性名 = "属性值")
class 类名 {
...
}

通过反射获取注解

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
/**
* 定义一个名为Mapper的注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Mapper {}

/**
* 定义一个名为Select的注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Select {
String value();
}

/**
* 分别在类上和方法上使用`@Mapper`和`@Select`注解,做测试
*/
@Mapper
interface GoodsDao {

@Select("SELECT * FROM tb_goods")
public abstract void findGoods();

}

public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("com.test.GoodsDao");

/**
* 判断是否存在`Mapper.class`注解
*/
boolean flag = cls.isAnnotationPresent(Mapper.class);
System.out.println(flag);

/**
* 获取已标注`Mapper.class`的注解
* 如果不存在返回null,如果存在返回注解名
*/
Mapper key = cls.getDeclaredAnnotation(Mapper.class);
System.out.println(key);

/**
* 获取注解中的属性值
*/
Method method = cls.getDeclaredMethod("findGoods");
Select select = method.getDeclaredAnnotation(Select.class);
String sql = select.value();
System.out.println(sql);

}
}

完成