Java 注解



什么是注解?

Java 注解(Annotation)又称为“元数据”,是指对程序进行标注和解释。它为我们在代码中添加信息提供了一种形式化的方法。

注解和注释的区别:

  • 注释:给程序员看的。
  • 注解:给编译器看的。

使用注解进行配置的优势:使得代码更加简洁、方便。

注意事项:

  1. 想用好注解,前提是熟悉 Java 的反射机制(注解的解析完全依赖于反射)。
  2. 不要滥用注解。日常编程过程中很少会接触和使用注解,只有在做设计且不想让设计有过多的配置时,才会考虑使用。

自定义注解

格式:

public @interface 注解名称 {
    public 属性类型 属性名() default 默认值;
}
  1. @interface用来声明一个注解。
  2. 其中的每一个方法实际上是声明了一个配置参数:方法的名称就是参数的名称,返回值类型就是参数的类型。
  3. 可以通过 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
posted @ 2021-10-04 19:47  Juno3550  阅读(79)  评论(0编辑  收藏  举报