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)中被广泛应用。