杰瑞科技汇

attribute java 从

您提到的 "attribute" 在注解的上下文中,通常指的是注解的元素成员,我们可以把它理解为“配置项”或“参数”。

attribute java 从-图1
(图片来源网络,侵删)

什么是注解?

注解是 Java 的一种元数据,它不是程序本身,但可以用来修饰程序(类、方法、变量、包等),为代码提供一些额外的信息,就像给代码贴上“标签”一样。

它的核心作用是:

  • 编译检查@Override,告诉编译器这个方法是重写父类的方法,如果写错了,编译器会报错。
  • 配置和部署@SpringBootApplication@RestController,在 Spring 框架中,这些注解用来标记一个类是应用程序的入口或是一个 Web 控制器。
  • 代码生成@Data (Lombok),在编译时自动为类生成 getter、setter、toString 等方法。
  • 运行时处理@Deprecated,标记一个方法或类已过时,或者在运行时通过反射获取注解信息,实现某些逻辑。

如何定义一个注解?

使用 @interface 关键字来定义一个注解,一个注解定义看起来像一个接口。

// 定义一个名为 "MyAnnotation" 的注解
public @interface MyAnnotation {
}

这是一个最简单的注解,它没有任何“属性”。

attribute java 从-图2
(图片来源网络,侵删)

如何为注解添加“属性”(Elements)?

注解的“属性”在定义时,是以“无参方法”的形式出现的,方法名就是属性名,返回值类型就是属性的类型。

基本语法:

public @interface MyAnnotation {
    // 定义一个名为 "value" 的属性,类型为 String
    String value();
    // 定义一个名为 "count" 的属性,类型为 int,有默认值 10
    int count() default 10;
    // 定义一个名为 "enabled" 的属性,类型为 boolean,有默认值 true
    boolean enabled() default true;
}

关键点:

  • 属性类型:可以是基本类型(int, float, boolean 等)、StringClass、枚举类型,或者它们的一维数组。
  • 默认值:使用 default 关键字为属性提供默认值,如果一个属性有默认值,在使用该注解时就可以不指定这个属性。
  • 特殊属性 value:如果一个注解只有一个名为 value 的属性,那么在使用时,可以直接赋值,而不需要写成 value = "xxx" 的形式。

如何使用注解?

在要修饰的元素前面加上 和注解名称即可。

attribute java 从-图3
(图片来源网络,侵删)

示例 1:使用带属性的注解

假设我们有上面定义的 MyAnnotation

@MyAnnotation(
    value = "This is a class", // 为 value 属性赋值
    count = 5,                  // 为 count 属性赋值(覆盖默认值 10)
    enabled = true              // 使用默认值 true,也可以不写
)
public class MyClass {
    @MyAnnotation(value = "This is a method", count = 100)
    public void myMethod() {
        // ...
    }
}

示例 2:使用特殊属性 value

假设我们定义一个简单的注解:

public @interface SimpleAnnotation {
    String value();
}

使用时:

// 写法一:标准写法
@SimpleAnnotation(value = "Hello")
public class TestClass {}
// 写法二:简化写法(因为只有一个 value 属性)
@SimpleAnnotation("Hello")
public class TestClass {}

元注解:如何控制注解本身?

元注解是用于修饰其他注解的注解,它们可以控制注解的生命周期、使用范围等。

常用的元注解有:

  • @Target:定义注解可以修饰哪些程序元素。

    • ElementType.TYPE:类、接口、枚举
    • ElementType.METHOD:方法
    • ElementType.FIELD:字段(成员变量)
    • ElementType.PARAMETER:参数
    • ElementType.CONSTRUCTOR:构造器
    • ElementType.ANNOTATION_TYPE:注解
    • ElementType.PACKAGE:包
    • ElementType.LOCAL_VARIABLE:局部变量
    • ElementType.RECORD_COMPONENT:记录组件 (Java 14+)
  • @Retention:定义注解的生命周期。

    • RetentionPolicy.SOURCE:只在源码中存在,编译时被丢弃。
    • RetentionPolicy.CLASS:在 .class 文件中存在,但运行时被 JVM 丢弃(默认策略)。
    • RetentionPolicy.RUNTIME:在运行时也存在,可以通过反射读取,这是最强大的策略。
  • @Documented:表示该注解会被包含在 Javadoc 文档中。

  • @Inherited:表示被注解的类会被其子类继承。

示例:定义一个只能在类和方法上使用,并且在运行时可通过反射访问的注解

import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD}) // 可以用在类和方法上
@Retention(RetentionPolicy.RUNTIME)            // 运行时有效
@Documented                                   // 会包含在 Javadoc 中
public @interface MyRuntimeAnnotation {
    String author();
    String date() default "2025-01-01";
}

运行时处理:通过反射读取注解信息

只有 RetentionPolicy.RUNTIME 的注解才能在运行时被读取,这通常通过 Java 反射 API 来实现。

示例:

// 1. 定义一个运行时注解
@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeAnnotation {
    String value();
}
// 2. 在类上使用该注解
@MyRuntimeAnnotation("This is a test class")
public class TestAnnotationReflection {
    public static void main(String[] args) {
        try {
            // 3. 获取 TestAnnotationReflection 类的 Class 对象
            Class<?> clazz = TestAnnotationReflection.class;
            // 4. 获取类上的注解
            MyRuntimeAnnotation annotation = clazz.getAnnotation(MyRuntimeAnnotation.class);
            // 5. 检查注解是否存在并打印信息
            if (annotation != null) {
                System.out.println("Found annotation on class: " + annotation.annotationType().getName());
                System.out.println("Annotation value: " + annotation.value());
            } else {
                System.out.println("No annotation found on the class.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出:

Found annotation on class: MyRuntimeAnnotation
Annotation value: This is a test class

概念 解释 示例
注解 一种元数据,用于修饰代码。 @Override, @Test
定义 使用 @interface 关键字。 public @interface MyAnnotation {}
属性 在注解内部定义的无参方法。 String name();
int age() default 18;
使用 在代码前加上 和注解名。 @MyAnnotation(name = "Alice")
元注解 修饰注解的注解,控制其行为。 @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
处理 通过反射在运行时读取 RUNTIME 级别的注解。 clazz.getAnnotation(MyAnnotation.class)

希望这个详细的解释能帮助你完全理解 Java 中的注解和它的“属性”!

分享:
扫描分享到社交APP
上一篇
下一篇