Java 注解
什么是注解?
Java 注解(Annotation)又称为“元数据”,是指对程序进行标注和解释。它为我们在代码中添加信息提供了一种形式化的方法。
注解和注释的区别:
- 注释:给程序员看的。
- 注解:给编译器看的。
使用注解进行配置的优势:使得代码更加简洁、方便。
注意事项:
- 想用好注解,前提是熟悉 Java 的反射机制(注解的解析完全依赖于反射)。
- 不要滥用注解。日常编程过程中很少会接触和使用注解,只有在做设计且不想让设计有过多的配置时,才会考虑使用。
自定义注解
格式:
public @interface 注解名称 {
public 属性类型 属性名() default 默认值;
}
- @interface用来声明一个注解。
- 其中的每一个方法实际上是声明了一个配置参数:方法的名称就是参数的名称,返回值类型就是参数的类型。
- 可以通过 default 来声明参数的默认值。
属性类型只能是:
- 基本数据类型
- String
- Class
- 注解
- 枚举
- 以上类型的一维数组
元注解:
元注解名 | 说明 |
---|---|
@Target | 指定了注解能在哪里使用 |
@Retention | 可以理解为保留时间(生命周期) |
@Inherited | 表示修饰的自定义注解可以被子类继承 |
@Documented | 表示该自定义注解,会出现在 API 文档里面 |
综合示例
注解类:
package com.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.Map;
enum Season {
SPRING, SUMMER, AUTUMN, WINTER;
}
// 空注解
@interface Anno2 {
}
// 有属性的注解
@Retention(value = RetentionPolicy.RUNTIME) // 想要用反射操作注解,就要定义注解的保留策略
@interface Anno1 {
// 定义一个基本类型的属性
int id() default 0;
// 定义一个String类型的属性
public String name() default "demo";
// 定义一个Class类型的属性
public Class gid() default Anno2.class;
// 定义一个注解类型的属性
public Anno2 anno() default @Anno2;
// 定义一个枚举类型的属性
public Season season() default Season.SPRING;
// 以上类型的一维数组
// int数组
public int[] arr() default {1, 2, 3, 4, 5};
// 枚举数组
public Season[] seasons() default {Season.SPRING,Season.SUMMER};
// 后期我们在使用注解的时候,如果我们只需要给注解的value属性赋值,那么value就可以省略
public String value();
}
// 注解类
// 在使用注解时,如果注解里面的属性没有指定默认值,那么我们就需要手动给出注解属性的设置值
@Anno1(name="anno class", gid=Anno2.class, value="类注解")
public class UserAnnotation {
@Anno1(name="param", id=1, gid=Anno2.class, value="属性注解")
private Integer age;
@Anno1 (name="construct", id=2, gid=Anno2.class, value="构造方法注解")
public UserAnnotation(){
}
@Anno1(name="public method", id=3, gid=Anno2.class, value="方法注解")
public void a(){
Map m = new HashMap(0);
}
@Anno1(name="protected method", id=4, gid=Anno2.class, value="方法注解")
protected void b(){
Map m = new HashMap(0);
}
@Anno1(name="private method", id=5, gid=Anno2.class, value="方法注解")
private void c(){
Map m = new HashMap(0);
}
}
测试类:
package com.annotation;
import com.annotation.Anno1;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
// 测试类
public class Test {
public static void parseTypeAnnotation() throws ClassNotFoundException {
Class clazz = Class.forName("com.annotation.UserAnnotation");
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
Anno1 anno1 = (Anno1) annotation;
System.out.println("id= " + anno1.id() + "; name= " + anno1.name() + "; gid = " + anno1.gid());
}
}
public static void parseMethodAnnotation() {
Method[] methods = UserAnnotation.class.getDeclaredMethods();
for (Method method : methods) {
boolean hasAnnotation = method.isAnnotationPresent(Anno1.class);
if (hasAnnotation) {
Anno1 annotation = method.getAnnotation(Anno1.class);
System.out.println("method = " + method.getName()
+ " ; id = " + annotation.id() + " ; description = "
+ annotation.name() + "; gid= " + annotation.gid());
}
}
}
public static void parseConstructAnnotation() {
Constructor[] constructors = UserAnnotation.class.getConstructors();
for (Constructor constructor : constructors) {
boolean hasAnnotation = constructor.isAnnotationPresent(Anno1.class);
if (hasAnnotation) {
Anno1 annotation = (Anno1) constructor.getAnnotation(Anno1.class);
System.out.println("constructor = " + constructor.getName()
+ " ; id = " + annotation.id() + " ; description = "
+ annotation.name() + "; gid= " + annotation.gid());
}
}
}
public static void main(String[] args) throws ClassNotFoundException {
parseTypeAnnotation();
parseMethodAnnotation();
parseConstructAnnotation();
}
}
运行结果:
id= 0; name= anno class; gid = interface com.annotation.Anno2
method = c ; id = 5 ; description = private method; gid= interface com.annotation.Anno2
method = b ; id = 4 ; description = protected method; gid= interface com.annotation.Anno2
method = a ; id = 3 ; description = public method; gid= interface com.annotation.Anno2
constructor = com.annotation.UserAnnotation ; id = 2 ; description = construct; gid= interface com.annotation.Anno2