java枚举高级用法
枚举常见的使用方式是当作常量,但有时需要将不同的行为与每个常量关联起来。例如我们编写一个枚举类型,来表示计算器的四大基本操作,你想要提供一个方法来执行每个常量所表示的算术运算。下面来展示几种实现方式:
1. EnumMap
使用EnumMap将枚举项和行为进行关联(可用于实现命令模式)
EnumMap的使用,参考:https://mp.weixin.qq.com/s/2hVYKfmKuiyB5FlGZaDcxw
import java.util.EnumMap;public class EnumMapDemo {private static final EnumMap<Operation, IOperation> operationMap = new EnumMap<>(Operation.class);static {//枚举项和行为的映射operationMap.put(Operation.PLUS, new PlusOperation());operationMap.put(Operation.MINUS, new MinusOperation());operationMap.put(Operation.TIMES, new TimesOperation());operationMap.put(Operation.DIVIDE, new DivideOperation());}public static void main(String[] args) {IOperation plus = operationMap.get(Operation.PLUS);IOperation minus = operationMap.get(Operation.MINUS);System.out.println(plus.handle(2, 3));System.out.println(minus.handle(2, 3));}}enum Operation {PLUS, MINUS, TIMES, DIVIDE;
}interface IOperation {double handle(double x, double y);
}class PlusOperation implements IOperation {@Overridepublic double handle(double x, double y) {return x + y;}
}class MinusOperation implements IOperation {@Overridepublic double handle(double x, double y) {return x - y;}
}class TimesOperation implements IOperation {@Overridepublic double handle(double x, double y) {return x * y;}
}class DivideOperation implements IOperation {@Overridepublic double handle(double x, double y) {return x / y;}
}
2. 使用switch
使用switch关键字将枚举项和行为进行关联
public enum Operation {PLUS, MINUS, TIMES, DIVIDE;public double handle(double x, double y) {switch (this) {case PLUS:return x + y;case MINUS:return x - y;case TIMES:return x * y;case DIVIDE:return x / y;}//throw是必须的,否则编译不通过throw new AssertionError("Unknown op:" + this);}public static void main(String[] args) {System.out.println(Operation.PLUS.handle(2, 3));}
}
这段代码能用,但是不太好看。如果没有 throw 语句,它就不能进行编译,虽然从技术角度来看代码的结束部分是可以执行的,但是实际上是不可能执行到这行代码的。更糟糕的是,这段代码很脆弱。如果新增一个枚举常量,却忘记给switch添加相应的条件,枚举类型可以编译,但是运行新的枚举常量时,运行就会失败。
3. 枚举项实现抽象方法
在枚举类型中声明一个抽象的handle方法,并在特定于常量的类主体中,用具体的方法覆盖每个常量的抽象handle方法,这种方法被称为特定于常量的方法实现。
常量和行为高度耦合(关联)。
public enum Operation {PLUS {@Overridepublic double handle(double x, double y) {return x + y;}},MINUS {@Overridepublic double handle(double x, double y) {return x - y;}},TIMES {@Overridepublic double handle(double x, double y) {return x * y;}},DIVIDE {@Overridepublic double handle(double x, double y) {return x / y;}};public abstract double handle(double x, double y);public static void main(String[] args) {System.out.println(Operation.PLUS.handle(2, 3));}
}