Skip to content

java枚举使用

枚举定义

NOTE

只有name值的枚举就是简单枚举

如果定义了字段属性,就是带字段或方法的枚举

基本定义

java
public enum Color {
    RED, GREEN, BLUE;
}

带字段和方法的枚举:

java
public enum Color {
    RED("红色"), GREEN("绿色"), BLUE("蓝色");

    private final String description;

    Color(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}
  • 枚举常量 RED, GREEN, BLUE 实际上是枚举类的实例。
  • 构造函数是私有的,不能用 new 创建枚举对象。

枚举使用

基本使用

java
Color color = Color.RED;
System.out.println(color); // 输出: RED

遍历枚举值:

java
(Color color : Color.values()) {
    System.out.println(color);
}
// 输出: 红色、绿色、蓝色

获取枚举值(字符串转枚举)

java
Color color = Color.valueOf("红色");
System.out.println(color); // 输出:红色

枚举比较:

枚举常量可以用 ==.equals() 比较:

java
Color color = ...;
if (color == Color.RED) {}

String input = "RED";
Color.RED.name().equals(input);
Color.RED.name().equalsIgnoreCase(input); //大小写不敏感比较
  
Color color = Color.valueOf(input);
color == Color.RED;
  
String description = "红色";
Color.RED.getDescription().equals(input);

调用方法:

java
Color color = Color.RED;
System.out.println(color.getDescription()); // 输出: 红色

JSON序列化和反序列化(Fastjson)

  • FastJSON 默认会将枚举序列化为字符串(枚举的 name())。

  • 如果枚举包含字段并需要自定义序列化,可以通过 @JSONType 注解或编写自定义序列化器实现。

  • 简单枚举: 操作的是枚举的 name()

  • 带字段或方法的枚举: 默认情况下,FastJSON 仍然会将枚举序列化为 name()

  • 使用@JSONType注解:会把枚举当成对象来序列化,

    java
    @JSONType(serializeEnumAsJavaBean = true)
    enum Status {
        SUCCESS("Operation succeeded"), FAILURE("Operation failed");
    
        private final String description;
    
        Status(String description) {
            this.description = description;
        }
    
        public String getDescription() {
            return description;
        }
    }
    
    Response response = new Response(Status.SUCCESS, "Operation completed successfully.");
    // 序列化
    System.out.println(JSON.toJSONString(response)); // {"status":{"description":"Operation succeeded","name":"SUCCESS"},"message":"Operation completed successfully."}
  • 自定义序列化器: 每个枚举都需要单独定义,太复杂

    java
    class StatusSerializer implements ObjectSerializer {
        @Override
        public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
            Status status = (Status) object;
            serializer.write(status.getDescription()); // 序列化为描述字段
        }
    }
    
    Response response = new Response(Status.SUCCESS, "Operation completed successfully.");
    
    // 注册序列化器
    SerializeConfig config = SerializeConfig.globalInstance;
    config.put(Status.class, new StatusSerializer());
    
    // 序列化
    System.out.println(JSON.toJSONString(response, config)); //{"status":"Operation succeeded","message":"Operation completed successfully."}
    java
    class StatusDeserializer implements ObjectDeserializer {
        @Override
        public Status deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
            String description = parser.parseObject(String.class);
            for (Status status : Status.values()) {
                if (status.getDescription().equals(description)) {
                    return status;
                }
            }
            return null; // 未匹配到返回 null
        }
    
        @Override
        public int getFastMatchToken() {
            return 0;
        }
    }
    
    String json = "{\"status\":\"Operation succeeded\",\"message\":\"Operation completed successfully.\"}";
    
    // 注册反序列化器
    ParserConfig config = ParserConfig.global;
    config.putDeserializer(Status.class, new StatusDeserializer());
    
    // 反序列化
    Response response = JSON.parseObject(json, Response.class, config);
    System.out.println(response.getStatus()); // 输出:SUCCESS
    System.out.println(response.getMessage()); // 输出:Operation completed successfully.

switch语句中替换String

java
String color = "红色";

// 使用枚举替代 String
Color enumStatus = Color.valueOf(color);

switch (enumStatus) {
    case RED:
        System.out.println("color RED");
        break;
    case GREEN:
        System.out.println("color GREEN");
        break;
}

高级用法

  1. 实现接口:

枚举可以实现接口,从而具有多态的能力

java
interface Behavior {
    void action();
}

public enum Animal implements Behavior {
    DOG {
        @Override
        public void action() {
            System.out.println("Bark");
        }
    },
    CAT {
        @Override
        public void action() {
            System.out.println("Meow");
        }
    };
}

使用:

java
Animal.DOG.action(); // 输出:Bark
Animal.CAT.action(); // 输出:Meow
  1. 使用枚举单例:

枚举是实现单例模式的一种推荐方式,因为它天然是线程安全的。

java
public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Singleton is working");
    }
}

使用:

java
Singleton.INSTANCE.doSomething();
  1. 覆盖枚举的 toString 方法:
java
public enum Day {
    MONDAY {
        @Override
        public String toString() {
            return "Monday";
        }
    },
    TUESDAY {
        @Override
        public String toString() {
            return "Tuesday";
        }
    };
}
  1. 自定义序列化和反序列化:

如果需要自定义 JSON 序列化,可以使用 @JSONType 注解:

java
import com.alibaba.fastjson.annotation.JSONType;

@JSONType(serializeEnumAsJavaBean = true)
public enum Color {
    RED("红色"), GREEN("绿色"), BLUE("蓝色");

    private final String description;

    Color(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}