Skip to content

2026-08-27 · 枚举、Record、密封类——Java 提供的特殊类类型。

Java 枚举与特殊类

1. 枚举(enum)

用来定义一组固定的常量,比 static final 更安全:

java
// 定义枚举
public enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

// 使用
Season s = Season.SPRING;
System.out.println(s); // SPRING

枚举 vs 常量

java
// 常量方式(不安全,任何 int 都能传进来)
public static final int SPRING = 0;
public static final int SUMMER = 1;
void setSeason(int season) { }  // 传 999 也行,没人拦

// 枚举方式(安全,只能传枚举值)
void setSeason(Season season) { }  // 只能传 SPRING/SUMMER/AUTUMN/WINTER

枚举可以有属性和方法

java
public enum Season {
    SPRING("春天", 3),
    SUMMER("夏天", 6),
    AUTUMN("秋天", 9),
    WINTER("冬天", 12);  // 注意分号!

    private final String name;
    private final int month;

    // 构造方法(必须 private,可省略 private 关键字)
    Season(String name, int month) {
        this.name = name;
        this.month = month;
    }

    public String getName() { return name; }
    public int getMonth() { return month; }
}

System.out.println(Season.SPRING.getName()); // 春天
System.out.println(Season.SUMMER.getMonth()); // 6

枚举本质是一个特殊的 final class,继承自 java.lang.Enum

枚举常用方法

java
Season s = Season.SPRING;

s.name();       // "SPRING"(枚举常量名)
s.ordinal();    // 0(枚举常量的序号,从 0 开始)

Season.valueOf("SUMMER"); // Season.SUMMER(字符串转枚举)

Season[] arr = Season.values(); // 所有枚举值的数组
for (Season season : arr) {
    System.out.println(season.getName());
}

枚举配合 switch

java
Season s = Season.SUMMER;

switch (s) {
    case SPRING -> System.out.println("万物复苏");
    case SUMMER -> System.out.println("烈日炎炎");
    case AUTUMN -> System.out.println("秋高气爽");
    case WINTER -> System.out.println("银装素裹");
}

枚举的实际应用

java
// 状态码枚举
public enum OrderStatus {
    CREATED, PAID, SHIPPED, COMPLETED, CANCELLED
}

// 错误码枚举
public enum ErrorCode {
    SUCCESS(0, "成功"),
    PARAM_ERROR(1001, "参数错误"),
    NOT_FOUND(1002, "未找到");

    private final int code;
    private final String message;

    ErrorCode(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() { return code; }
    public String getMessage() { return message; }
}

Spring Boot 项目里,枚举常用于状态码、错误码、订单状态等固定值场景。

2. Record(Java 16+)

不可变数据类的语法糖,自动生成构造方法、getter、equals、hashCode、toString:

java
// 传统写法(需要手写一堆代码)
public class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() { return x; }
    public int getY() { return y; }

    @Override
    public boolean equals(Object o) { /*...*/ }

    @Override
    public int hashCode() { /*...*/ }

    @Override
    public String toString() { /*...*/ }
}

// Record 写法(一行完成)
public record Point(int x, int y) {}

// 使用
Point p = new Point(3, 5);
System.out.println(p.x());     // 3(注意:不是 getX())
System.out.println(p.y());     // 5
System.out.println(p);         // Point[x=3, y=5]

Record 特点

  • 自动生成:构造方法、x()/y() 方法、equals()hashCode()toString()
  • 属性是 private final(不可修改)
  • 可以加自定义方法:
java
public record Point(int x, int y) {
    // 自定义方法
    public double distanceTo(Point other) {
        return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
    }
}

Record 适合 DTO(数据传输对象)、VO(值对象)等只存数据的类。Spring Boot 里用 Record 接收请求参数很方便。