ZetCode

Java 注解

上次修改时间:2024 年 7 月 4 日

在本文中,我们讨论 Java 注解。

注解是一种特殊的代码元素,它提供关于程序的附加信息。 它们使用 @ 符号附加到类、方法、字段和其他程序元素。

注解本身并不直接影响代码的运行方式,而是提供可供各种工具使用的元数据

以下是关于 Java 注解的一些关键点

@Override 注解

Java 中的 @Override 注解专门用于继承中的方法重写。 它是一个标记注解,用于提高代码清晰度并在编译期间捕获错误。

以下是 @Override 的作用

@Override 对于重写方法不是强制性的。 编译器通常可以根据签名判断一个方法是否打算覆盖。 但是,为了更好的代码清晰度和及早发现潜在错误,通常认为使用 @Override 是一种好的做法。

@Override 不用于实现接口中的方法。 接口只声明方法,实现接口的子类必须提供自己的实现。 编译器本质上会检查这种关系。

Main.java
class User {

    private final String firstName;
    private final String lastName;
    private final String occupation;

    public User(String firstName, String lastName, String occupation) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.occupation = occupation;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getOccupation() {
        return occupation;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("firstName='").append(firstName).append('\'');
        sb.append(", lastName='").append(lastName).append('\'');
        sb.append(", occupation='").append(occupation).append('\'');
        sb.append('}');
        return sb.toString();
    }
}


void main() {

    User[] users = {
        new User("John", "Doe", "gardener"),
        new User("Roger", "Roe", "driver"),
        new User("Paul", "Smith", "teacher"),
    };

    for (User user : users) {
        System.out.println(user);
    }

}

在示例中,我们重写了 ObjecttoString 方法。 该方法用 @Override 注释。 如果该函数与父函数不匹配(例如,我们使用 private 而不是 public),我们会收到警告:无法降低从 Object 继承的方法的可见性

@Deprecated 注解

Java 中的 @Deprecated 注解用于标记不再推荐使用的类、方法、字段或构造函数。 它可以作为对开发人员的警告,他们应该避免使用这些元素并考虑替代方案。

@Deprecated 注解的关键特性

@Deprecated 注解的其他特性(Java 9 及更高版本)

Main.java
class PassWordGenerator {

    @Deprecated
    public String generatePassword() {
        return "generated password";
    }

    public String generateSecurePassword() {
        return "a secure password";
    }
}

// @SuppressWarnings("deprecation")
void main() {

    var pgen = new PassWordGenerator();
    System.out.println(pgen.generateSecurePassword());
    System.out.println(pgen.generatePassword());
}

在示例中,我们用 @Deprecated 注释标记 generatePassword,因为它将被更安全的替代方案取代。

可以使用 @SuppressWarnings("deprecation") 注解来抑制 @Deprecated 注解。

自定义注解

我们可以在 Java 中创建自己的注解。 下表总结了自定义 Java 注解的关键要素

元素 描述
@interface 创建自定义注解的声明。
@Target 指定注解可以应用的位置(字段、类、方法等)。
@Retention 确定注解信息保留的时间(编译时或运行时)。
元素(方法) 定义注解的属性或参数(带有数据类型和默认值)。
文档注释 用于记录注解及其用法的可选注释。

下一个示例创建一个自定义注解。

com/zetcode/ClassDescription.java
package com.zetcode;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassDescription {
    String description();
}

我们有一个 ClassDescription,它以类为目标。

com/ztetcode/AnnotationProcessor.java
package com.zetcode;

import java.util.List;
import java.util.Optional;

public class AnnotationProcessor {

    public void process(List<Object> objects) {
        objects.forEach(obj -> {

            Class<?> clazz = obj.getClass();
            ClassDescription annotation = clazz.getAnnotation(ClassDescription.class);

//            if (annotation != null) {
//                System.out.println(annotation.annotationType().getName());
//                System.out.println(annotation.description());
//            }

            Optional.ofNullable(annotation)
                    .ifPresentOrElse(
                            ann -> {
                                System.out.println(ann.annotationType().getName());
                                System.out.println(ann.description());
                            },
                            () -> System.out.println("No annotation found")
                    );


        });
    }
}

AnnotationProcessor 将处理注解。

com/zetcode/CustomAnnotation.java
package com.zetcode;

import java.util.List;

@ClassDescription(description = "this is a User class")
class User {

}

@ClassDescription(description = "this is a Test class")
class Test {

}

class Hello {

}


public class CustomAnnotation {

    private String field;

    public static void main(String[] args) {

        List<Object> objects = List.of(new User(), new Test(), new Hello());

        var processor = new AnnotationProcessor();
        processor.process(objects);

    }
}

我们有两个类用 @ClassDescription 装饰。 我们使用 AnnotationProcessor 处理实例对象,它将打印装饰类的描述。

来源

Java 注解 - 教程

在本文中,我们介绍了 Java 中的注解。 我们展示了如何使用现有注解以及如何创建一个自定义注解。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有Java教程