JAVA高级(4)—— 枚举

1、问题

在枚举出现之前,如果想要表示一组特定的离散值,往往使用一些常量

public class Entity {  
    public static final int VIDEO = 1;//视频  
    public static final int AUDIO = 2;//音频  
    public static final int TEXT = 3;//文字  
    public static final int IMAGE = 4;//图片  
      
    private int id;  
    private int type;  
      
    public int getId() {  
        return id;  
    }  
    public void setId(int id) {  
        this.id = id;  
    }  
    public int getType() {  
        return type;  
    }  
    public void setType(int type) {  
        this.type = type;  
    }  
}  

缺点:
1)代码可读性差、易用性低;像是setType(2)这种用法也是在所难免,因为它完全合法,不是每个人都能够建立起用常量名代替数值,从而增加程序可读性、降低耦合性的意识。
2)类型不安全;setType(-1)这样的调用是合法的,但它并不合理,今后会为程序带来种种问题。
3)耦合性高,扩展性差;假如,因为某些原因,需要修改Entity类中常量的值,那么,所有用到这些常量的代码也就都需要修改——当然,要仔细地修改,万一漏了一个,那可不是开玩笑的。同时,这样做也不利于扩展。例如,假如针对类别做了一个有效性验证,如果类别增加了或者有所变动,则有效性验证也需要做对应的修改,不利于后期维护。

2、枚举

  • 一种特殊的类,其中的每个元素都是该类的一个实例对象。
  • 可以定义方法,并且实现接口。继承自java.lang.Enum类,因此enum不可以再继承其他的类。
  • 枚举元素必须位于枚举体中最开始部分,以分号结尾。
  • 通常用来表示诸如颜色、方式、类别、状态等等数目有限、形式离散、表达又极为明确的量
  • 用到枚举类型,全部对象都会被实例化,因为都是public static final修饰的
带有构造方法的枚举
public enum TypeEnum {  
    VIDEO(1, "视频"), AUDIO(2, "音频"), TEXT(3, "文本"), IMAGE(4, "图像");  
      
    int value;  
    String name;  
      
    TypeEnum(int value, String name) {  
        this.value = value;  
        this.name = name;  
    }  
      
    public int getValue() {  
        return value;  
    }  
      
    public String getName() {  
        return name;  
    }  
}
带有抽象方法的枚举
    public enum TrafficLamp {
        RED(10) {
            @Override
            public TrafficLamp nextLamp() {
                return GREEN;
            }
        },
        GREEN(20) {
            @Override
            public TrafficLamp nextLamp() {
                return null;
            }
        };
        private int time;

        public abstract TrafficLamp nextLamp();

        TrafficLamp(int time) {
            this.time = time;
        }
    }

3、方法

  • name() String //返回此枚举实例的常量名称。如:RED
  • ordinal() // 返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
  • valueOf(String name) T //static方法,根据String转枚举实例
  • values() T[] //static方法,返回该枚举的所有值

4、EnumMap

专门为枚举类型量身定做的Map实现。虽然使用其它的Map实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用EnumMap会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值。这使得EnumMap的效率非常高。

public enum Phase {
    SOLID, LIQUID, GAS;
    public enum Transition {
        MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID), BOIL(LIQUID, GAS), CONDENSE(
                GAS, LIQUID), SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
        private final Phase src;
        private final Phase dst;

        Transition(Phase src, Phase dst) {
            this.src = src;
            this.dst = dst;
        }

        private static final Map> m = new EnumMap>(
                Phase.class);
        static {
            for (Phase p : Phase.values())
                m.put(p, new EnumMap(Phase.class));
            for (Transition trans : Transition.values())
                m.get(trans.src).put(trans.dst, trans);
        }

        public static Transition from(Phase src, Phase dst) {
            return m.get(src).get(dst);
        }
    }

    public static void main(String[] args) {
        for (Phase src : Phase.values())
            for (Phase dst : Phase.values())
                if (src != dst)
                    System.out.printf("%s to %s : %s %n", src, dst,
                            Transition.from(src, dst));
    }
}

参考文献

浅谈在Java开发中的枚举的作用和用法

你可能感兴趣的:(JAVA高级(4)—— 枚举)