Java中注解(annotation)的概念、示例、写法的一文详解。

Java 注解 @interface 详解

定义注解

public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

逐行解释

  • public @interface Report

    • 定义了一个名字叫 Report 的注解。
    • 它可以被用在类、方法、字段等地方(具体要看后续有没有加元注解 @Target@Retention)。
  • int type() default 0;

    • 定义了一个名为 type 的参数,类型是 int
    • default 0 表示如果使用注解时不写 type,它的默认值就是 0
  • String level() default "info";

    • 定义了一个 String 类型的参数,名字是 level
    • 默认值是 "info"
  • String value() default "";

    • 定义了一个常用参数 value,类型是 String
    • 默认值是空字符串 ""
    • 在注解里,如果你定义了 value() 参数,使用注解时可以只写值,不写 value=

使用示例

// 使用所有参数
@Report(type = 1, level = "warning", value = "检查数据合法性")
public class MyService {}

// 使用默认值
@Report
public class MyDefaultService {}

// 如果只设置 value,可以省略 "value="
@Report("只传入value参数")
public class MySimpleService {}

为什么注解参数写成方法形式?

很多人疑惑:既然是参数,为什么写成 type() 这种看起来像方法的形式?

本质原因

Java 注解(@interface)的语法设计,是基于接口的特殊语法糖

例如:

public @interface Report {
    int type() default 0;
}

编译器会生成:

public interface Report extends java.lang.annotation.Annotation {
    int type();   // 一个抽象方法
}

所以:

  • type() 其实是一个抽象方法。
  • 但在注解语法里,它表达的意义是“参数”。
  • default 0 就相当于给这个抽象方法一个默认返回值。

为什么不用变量?

Java 设计者考虑:

  1. 注解必须能在字节码层被反射机制识别。
  2. 注解的参数必须是编译期常量(int、String、Class、enum、注解、数组)。
  3. 语法上最简单的方式,就是复用接口里的抽象方法写法。

因此 type()level()value() 看似方法,实际上是 注解元素(annotation element)


使用和反射读取

@Report(type = 2, level = "error", value = "严重错误")
public class Demo {}

反射读取:

Report r = Demo.class.getAnnotation(Report.class);
System.out.println(r.type());   // 2
System.out.println(r.level());  // "error"
System.out.println(r.value());  // "严重错误"

这里的 r.type() 真的是方法调用,但它返回的就是注解参数的值。


总结

  • 注解里的参数写成“方法”的形式,是因为注解本质上就是接口。
  • type()level()value() 看似方法,实际是“注解元素定义”。
  • 注解参数可以有默认值,并且可以通过反射读取。
posted @ 2025-08-18 10:21  AlphaGeek  阅读(77)  评论(0)    收藏  举报