1. 枚举基础与字符串表示

在 Java 中,枚举(Enum)是一种特殊的类,用于定义一组固定的常量。每个枚举常量都有一个默认的字符串表示形式,即其名称。

public enum Color {
    RED, GREEN, BLUE
}

public class Main {
    public static void main(String[] args) {
        Color color = Color.RED;
        System.out.println(color); // 输出: RED
        System.out.println(color.name()); // 输出: RED
    }
}

枚举的 toString() 方法默认返回枚举常量的名称,与 name() 方法返回的结果相同。但 toString() 可以被重写,而 name() 是 final 方法,不能被重写。

2. 枚举与字符串的相互转换

2.1 字符串转枚举

使用 Enum.valueOf() 方法可以将字符串转换为对应的枚举常量:

String colorStr = "GREEN";
Color color = Color.valueOf(colorStr); // 返回 Color.GREEN
System.out.println(color); // 输出: GREEN

注意事项:

  • 字符串必须与枚举常量的名称完全匹配(区分大小写)
  • 如果字符串不匹配任何枚举常量,会抛出 IllegalArgumentException
  • 可以使用 try-catch 处理异常,或先检查字符串是否有效

2.2 枚举转字符串

除了使用 toString()name() 方法,还可以为枚举添加自定义属性:

public enum Status {
    ACTIVE("激活"),
    INACTIVE("未激活"),
    DELETED("已删除");
    
    private final String description;
    
    Status(String description) {
        this.description = description;
    }
    
    public String getDescription() {
        return description;
    }
    
    @Override
    public String toString() {
        return description;
    }
}

public class Main {
    public static void main(String[] args) {
        Status status = Status.ACTIVE;
        System.out.println(status.name()); // 输出: ACTIVE
        System.out.println(status.toString()); // 输出: 激活
        System.out.println(status.getDescription()); // 输出: 激活
    }
}

3. 高级应用场景

3.1 枚举映射到数据库值

在实际开发中,经常需要将枚举值存储到数据库。可以使用自定义的转换器:

public enum UserType {
    ADMIN("A", "管理员"),
    USER("U", "普通用户"),
    GUEST("G", "访客");
    
    private final String dbCode;
    private final String displayName;
    
    UserType(String dbCode, String displayName) {
        this.dbCode = dbCode;
        this.displayName = displayName;
    }
    
    public String getDbCode() {
        return dbCode;
    }
    
    public String getDisplayName() {
        return displayName;
    }
    
    // 根据数据库代码获取枚举
    public static UserType fromDbCode(String dbCode) {
        for (UserType type : values()) {
            if (type.dbCode.equals(dbCode)) {
                return type;
            }
        }
        throw new IllegalArgumentException("无效的用户类型代码: " + dbCode);
    }
}

3.2 枚举与 JSON 序列化

在使用 JSON 序列化框架(如 Jackson、Gson)时,可以自定义枚举的序列化和反序列化方式:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

public enum Priority {
    HIGH("high", 1),
    MEDIUM("medium", 2),
    LOW("low", 3);
    
    private final String jsonValue;
    private final int level;
    
    Priority(String jsonValue, int level) {
        this.jsonValue = jsonValue;
        this.level = level;
    }
    
    @JsonValue
    public String getJsonValue() {
        return jsonValue;
    }
    
    @JsonCreator
    public static Priority fromJsonValue(String jsonValue) {
        for (Priority priority : values()) {
            if (priority.jsonValue.equals(jsonValue)) {
                return priority;
            }
        }
        throw new IllegalArgumentException("无效的优先级: " + jsonValue);
    }
}

3.3 枚举与 Spring 请求参数

在 Spring MVC 中,可以直接使用枚举作为请求参数:

@RestController
public class UserController {
    
    @GetMapping("/users")
    public List<User> getUsers(@RequestParam UserType type) {
        // type 会自动从字符串转换为对应的枚举
        return userService.findByType(type);
    }
}

Spring 默认使用 Enum.valueOf() 进行转换,如果需要自定义转换逻辑,可以实现 Converter<String, Enum> 接口。

4. 最佳实践与注意事项

  1. 使用 name() 进行序列化:当需要稳定的字符串表示时,使用 name() 而不是 toString()
  2. 重写 toString() 提供友好显示:为终端用户显示时,可以重写 toString() 返回更友好的描述
  3. 添加 fromString() 方法:为枚举添加静态的 fromString() 方法,提供更灵活的反序列化
  4. 处理未知值:在反序列化时,考虑添加一个 UNKNOWN 枚举常量来处理未知的字符串值
  5. 性能考虑Enum.valueOf() 的时间复杂度是 O(n),对于频繁调用的场景,可以考虑使用 Map 缓存

5. 总结

Java 枚举与字符串的转换是日常开发中的常见需求。掌握 name()toString()valueOf() 等核心方法,并根据实际场景为枚举添加自定义属性和转换方法,可以大大提高代码的可读性和可维护性。无论是数据库存储、JSON 序列化还是 Web 请求处理,合理的枚举设计都能让代码更加优雅和健壮。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐