枚举使用的正确姿势

166 阅读2分钟

1.定义常量

在程序中被初始化不会再被修改的值,具有固定的含义。例如:name代表redis中的一个键值

为什么不直接在代码中使用这些值,而是定义成常量???

1.难以维护。值被多个地方使用,一旦业务含义改变需要更改,可能会出现漏改。

2.存在输入错误率。多次手动输入可能会出现输入错误的情况,增加后期排查工作量

3.理解不直观。有些值用1,2代表其状态,时间长了可能会忘记代表的意思

为了避免那些问题的出现,会定义统一的常量,起一个直观的名字。便于后期的维护

2.定义常量方法

1.常量类

public class RedisKey {
    private RedisKey(){}

    public static final String SASS_ORDER_STATUS = "sass_order_status";
}

2.接口

public interface RedisKey {
    String SASS_ORDER_STATUS = "sass_order_status";
}

//反编译结果
public interface com.test.enums.RedisKey {
  public static final java.lang.String SASS_ORDER_STATUS;
}

3.枚举

//不可以被继承,不可以继承其他类
public enum Color {
    RED;
}
//反编译结果
//被final修饰,继承了java.lang.Enum
public final class com.test.enums.Color3 extends java.lang.Enum<com.test.enums.Color3> {
  public static final com.test.enums.Color3 RED;
}

定义枚举类,在类的内部枚举实例。枚举的实例根据构造函数生成。可以直接使用枚举出来的实例。

可以实现接口,在实例中实现接口的方法。同样可以在类中定义抽象方法,并实现方法。

可以在类中定义方法使用。例如业务上需要将RED,YELLOW,BLACK进行存储记录,可以通过exist()方法来过滤值

public interface RandomColor {
    String getColor();
}


public enum Color implements RandomColor{

    RED("红色"){
        @Override
        public void getColorDesc() {
            System.out.println(this.getDesc());
        }

        @Override
        public String getColor() {
            System.out.println(this.name());
            return this.name();
        }
    },YELLOW("黄色") {
        @Override
        public void getColorDesc() {
            System.out.println(this.getDesc());
        }

        @Override
        public String getColor() {
            System.out.println(this.name());
            return this.name();
        }
    },BLACK("黑色","乌漆嘛黑") {
        @Override
        public void getColorDesc() {
            System.out.println(this.getDesc());
        }

        @Override
        public String getColor() {
            System.out.println(this.name());
            return this.name();
        }
    };
    @Getter
    private String desc;
    @Getter
    private String desc2;

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

    Color(String desc,String desc2){
        this.desc = desc;
        this.desc2 = desc2;
    }

    public static Boolean exist(String color){
        List<Color> result = Arrays.stream(values()).filter(x -> x.name().equals(color)).collect(Collectors.toList());
        if (result.isEmpty()){
            return false;
        }
        return true;
    }

    public static Color stringToColor(String color){
        try {
            return valueOf(color);
        } catch (IllegalArgumentException e) {
            log.error("Color enum:不存在该值");
        }
    }

    public abstract void getColorDesc();
}

存在抽象方法的类为抽象类,需要被其他方法继承重写抽象方法。枚举中即使存在抽象方法也不能被继承,因为构造方法被private修饰

//上述类反编译之后为抽象类
public abstract class com.test.enums.Color extends java.lang.Enum<com.test.enums.Color> implements com.test.enums.RandomColor {
  public static final com.test.enums.Color RED;

  public static final com.test.enums.Color YELLOW;

  public static final com.test.enums.Color BLACK;
}

image.png

3.1枚举好处?

1.限制输入。只能输入定义的值

public void test(Color color) {
    switch (color) {
        case RED:
        System.out.println("红色");
        break;
        case BLACK:
        System.out.println("黑色");
        break;
        case YELLOW:
        System.out.println("黄色");
        break;
        default:
            System.out.println("无色");
            break;
    }
}

2.回显数据自由

数据表里存储的color为RED,根据枚举进行回显,定义为红色,返回前端红色。定义为深红色,返回前端为深红色。
根据枚举RED("红色"),RED("深红色")回显

3.2枚举类中函数

valueOf(String name)

values()

RED.name()

RED.getDesc()

//valueOf(String name)
根据输入的name查找对应的实例

//values()
返回所有的实例

//RED.name()
返回实例名 “RED”

//RED.getDesc()
定义在类中的get方法 返回“红色”