如何優雅的在Java中使用枚舉enum

這是我參與更文挑戰的第1天,活動詳情查看: 更文挑戰java

根據【Effective Java】[第三版]第六章,枚舉與註解 所述,枚舉類型是指由一組固定的常量組成合法值的類型。數組

Talk is Cheap, Show me the Code!markdown

典型枚舉模板

下面是一個我的經常使用的枚舉enum模板。ide

代碼分爲n個部分:post

  1. 全部的枚舉變量 如代碼所示的部分:this

    TO_PAY, TO_DELIVER, TO_RECEIVE, FINISHED;
    複製代碼
  2. 枚舉的實例域spa

    private final int val;
    private final String name;
    複製代碼

    枚舉天生不可變,枚舉能夠輕鬆的使用「==」操做符。 枚舉的全部實例域均應該設置爲final。code

    另外,須要注意的是: 永遠不要根據枚舉的序數導出與它關聯的值,而是將它保存在一個實例域中【Effective Java】[第三版]p143。orm

  3. 其餘類型與枚舉類型相互轉換的方法接口

    /** * 枚舉轉int * @return */
    public int getVal() {
    	return val;
    }
        
        /** * int轉枚舉 * @param val * @return */
    public static OrderState getOrderState(int val) {
    	for (OrderState orderState : OrderState.values()) {
    		if (orderState.val == val) {
    			return orderState;
    		}
    	}
    	throw new RuntimeException("錯誤的訂單狀態");
    }
        
    複製代碼

    其中特別注意:values()這個方法,該方法按順序返回枚舉的全部值數組。

  4. 抽象方法

    這種方式能夠幫助咱們實現策略模式

    經過抽象方法,咱們能夠避免使用switch-case語句,以免在之後新增枚舉值時,忘記給對應值添加相關特殊操做。 枚舉中也可使用switch-case。

    【Effective Java】中:「枚舉中的switch-case語句適合於給外部的枚舉類型增長特定於常量的行爲」。

    另外,根據【Effective Java】[第三版]第38條,咱們能夠用接口模擬可擴展的枚舉。

/** * 訂單狀態 */
public enum OrderState {
	TO_PAY("待付款", 0) {
		@Override
		public boolean deliver() {
			return false;
		}
	},
	TO_DELIVER("待發貨", 1) {
		@Override
		public boolean deliver() {
			return true;
		}
	},
	TO_RECEIVE("待收貨", 2) {
		@Override
		public boolean deliver() {
			return false;
		}
	},
	FINISHED("已完成", 3) {
		@Override
		public boolean deliver() {
			return false;
		}
	};
	
	/** * 枚舉天生不可變,全部的域都應聲明爲final */
	private final int val;
	private final String name;
	
	/** * 私有修飾,防止外部調用 * @param name * @param val */
	private OrderState(String name, int val) {
		this.name = name;
		this.val = val;
	}

	/** * 枚舉轉int * @return */
	public int getVal() {
		return val;
	}

	public String getName() {
		return name;
	}
	
	/** * int轉枚舉 * @param val * @return */
	public static OrderState getOrderState(int val) {
		for (OrderState orderState : OrderState.values()) {
			if (orderState.val == val) {
				return orderState;
			}
		}
		throw new RuntimeException("錯誤的訂單狀態");
	}
	
	/** * 抽象方法:發貨 * @return */
	public abstract boolean deliver();
	
}

複製代碼
什麼時候應該使用枚舉

每當須要一組固定常量並在編譯時就知道其成員的時候,就應該使用枚舉。 可是,枚舉類型中的常量集並不必定要始終保持不變。

另外的EnumMap我並不常常使用,不作敘述。

枚舉的小缺陷

裝載和初始化枚舉時,須要空間與時間成本,幾乎能夠忽略。

相關文章
相關標籤/搜索