Skip to content

Java 枚举与注解

本章我们将学习两个 Java 中用于定义类型和元数据的重要概念:枚举(Enumeration)和注解(Annotation)。

枚举 (Enum)

枚举是一种特殊的 Java 类,它允许我们为一组固定的常量赋予有意义的名称。使用枚举可以增强代码的可读性、类型安全性和可维护性。

  • 使用 enum 关键字来定义一个枚举类型。
  • 枚举的常量成员在内部都是 public static final 的,且它们是该枚举类型的实例。

定义和使用枚举

java
// 定义一个表示星期的枚举
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public class EnumExample {
    public static void main(String[] args) {
        // 将枚举常量赋值给变量
        Day today = Day.WEDNESDAY;

        // 在 switch 语句中使用枚举
        switch (today) {
            case MONDAY:
                System.out.println("开始新的一周!");
                break;
            case FRIDAY:
                System.out.println("快要周末了!");
                break;
            default:
                System.out.println("平常的一天。");
                break;
        }

        // 遍历所有枚举常量
        System.out.println("\n所有星期:");
        for (Day day : Day.values()) {
            System.out.println(day);
        }

        // 获取枚举常量的名称和序号
        System.out.println("\n今天是: " + today.name());
        System.out.println("序号是: " + today.ordinal()); // 序号从 0 开始
    }
}

带属性和方法的枚举

枚举远比一组常量要强大。它可以拥有自己的属性、构造方法和普通方法。

  • 枚举的构造方法必须是 private 或包私有的。
  • 定义常量时,可以通过括号传递参数给构造方法。
java
public enum Planet {
    // 定义常量并关联属性
    MERCURY(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    EARTH(5.976e+24, 6.37814e6),
    MARS(6.421e+23, 3.3972e6);

    // 枚举的属性
    private final double mass;   // 质量 (kg)
    private final double radius; // 半径 (m)

    // 枚举的构造方法(隐式为 private)
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    // 枚举的方法
    public double surfaceGravity() {
        final double G = 6.67300E-11;
        return G * mass / (radius * radius);
    }
}

// 使用
// double earthGravity = Planet.EARTH.surfaceGravity();
// System.out.printf("地球表面重力: %f m/s^2%n", earthGravity);

注解 (Annotation)

注解是添加到 Java 代码中的一种元数据 (Metadata)。它们本身不直接影响代码的执行,但可以被编译器、工具或运行时库读取和处理,以实现特定的功能。

注解的用途

  • 为编译器提供信息:例如 @Override 告诉编译器一个方法是重写父类的方法,如果不是,编译器会报错。
  • 编译时处理:软件工具可以处理注解信息来生成代码、XML 文件等。
  • 运行时处理:一些注解可以在程序运行时通过反射被读取,从而影响程序的行为。

内置注解

Java 提供了一些标准的内置注解:

  • @Override: 检查该方法是否是重写父类或实现接口中的方法。
  • @Deprecated: 标记一个元素(类、方法等)已过时,不推荐使用。编译器会发出警告。
  • @SuppressWarnings: 告诉编译器忽略指定的警告信息。
  • @FunctionalInterface (Java 8+): 标记一个接口是函数式接口(只有一个抽象方法)。
java
public class BuiltInAnnotations {

    @Deprecated
    public void oldMethod() {
        System.out.println("这是一个过时的方法。");
    }

    @SuppressWarnings("deprecation")
    public void useOldMethod() {
        oldMethod(); // 编译器不会因为调用过时方法而发出警告
    }
}

自定义注解

我们也可以创建自己的注解。定义注解使用 @interface 关键字。

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

// 1. 定义一个注解
@Retention(RetentionPolicy.RUNTIME) // 指定注解的保留策略:在运行时可见
@Target(ElementType.METHOD) // 指定注解可以应用的目标:方法
public @interface MyCustomAnnotation {
    // 定义注解的元素(类似方法)
    String description() default "No description";
    int level();
}

// 2. 使用注解
public class MyService {
    @MyCustomAnnotation(description = "This is a test method", level = 5)
    public void performAction() {
        // ...
    }
}

自定义注解通常与反射 (Reflection) 结合使用,在运行时检查类或方法上是否存在某个注解,并根据注解的元素值来执行相应的逻辑。这在许多框架(如 Spring、JUnit)中被广泛应用。

本站内容仅供学习和研究使用。