一、简单介绍:
1.1 Java 5 开始,Java对元数据(metadata:描述数据的数据)提供支持,也就是注解/标签。注解被用来为程序元素(类、方法、成员变量等)设置元数据。所有的Annotation都是java.lang.annotation.Annotation接口的子接口,Annotation是一种特殊的接口: @interface Override{} 相当于: interface Override extends java.lang.annotation.Annotation{}
1.2 使用“注解”注意事项,必须有第三方参与才有意义:
- 要有注解标签;
- 被贴的程序元素(类、字段、构造器、方法等);
- 由第三方的程序来赋予注解特殊的功能(Java代码)。
二、JDK内置注解 :
注解 | 含义 |
@Override | 限定覆写父类方法 |
@Deprecated | 标记已过时,不推荐使用; JDK1.5之前使用文档注释来标记过时 |
@SuppressWarnings | 抑制编译器发出的警告 |
@SuppressWarnings(value="all") | |
@SafeVarargs | 抑制堆污染警告(Java7开始出现) |
**注解仅仅是抑制住编译器不要报警告,但是存在的风险依然存在,仅仅是不提示了。
三、元注解:
元注解:注解的元数据 --> 定义注解时,注解上的注解。
元注解 | 含义 | 参数 | ||||||||||||||||
@Retention | 表示注解可以保存到哪一个时期; 相关时期的值封装在RetentionPolicy枚举类中。 注意:一般自定义的注解, 使用RUNTIME(使用反射赋予注解功能) |
| ||||||||||||||||
@Target | 表示注解可以贴在哪些位置(类、方法、构造器上等等); 位置的常量封装在ElementType枚举类中。 |
| ||||||||||||||||
@Document | 标注的标签会保存到API文档中 | |||||||||||||||||
@Inherited | 标注的标签可以被子类所继承 |
四、自定义注解
定义注解的语法:
@Target(ElementType.TYPE) //标识该注解可以贴在类上/接口上
@Retentation(RetentationPolicy.RUNTIME) //标识该注解可以存在于JVM中(通过反射赋予功能)
public @interface 注解名称{
//抽象方法(在注解中也叫属性)
返回类型 方法名称() default 值;
......
}
注意:注解中抽象方法(属性)类型:只能是“基本类型、String、Class、annotation、枚举、数组”。
使用注解时,当只有一个属性并且名称为value,此时可以省略value:
@VIP(value="xx")或者@VIP("xx")
public class Employee{}
五、自定义注解实例
//VIP.java
//1、注解本身
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface VIP {
String name();
int age() default 18;
String[] hobby();
}
//Employee.java
//2、被贴元素
@SuppressWarnings("all")
@Deprecated
@VIP(name="zzyy" ,age=20, hobby = {"hahaha","java"})
public class Employee {
}
//VIPDemo.java
//3、第三方程序,赋予注解功能
public class VIPDemo {
// 需求:获取Employee上所有的注解
public static void main(String[] args) {
// 1、获取Employee字节码对象
Class<Employee> clz = Employee.class;
// 2、直接获取类上所有的注解
/*
* Annotation[] as = clz.getAnnotations(); for(Annotation a : as) {
* System.out.println(a); }
*/
// 判断Employee类上是否使用VIP注解
VIP a = clz.getAnnotation(VIP.class);
if (a == null) {
System.out.println("没有");
} else {
System.out.println("有");
System.out.println(a.name());
System.out.println(a.age());
System.out.println(a.hobby());
}
}
}
获取程序元素上的注解:注解可以贴在类(Class)、方法(Method)、字段(Field)、构造器(Constructor)上等,所以在Class/Method/Field/Constructor类中有获取注解的API。
比如:Annotation getAnnotation(Class annotationClass):如果存在该元素的指定类型的注释,则返回,否则返回null。 Annotation[] getAnnotations():返回此元素上存在的所有注释。 boolean isAnnotationPresent(Class annotationClass):判断当前成员上是否标注了某一个注解。