第三十一條 用例項域代替序數
列舉中有個方法, ordinal()方法,它的值是列舉常量在型別中的數字位置,如果把列舉裡面的內容物件看成是一個數組,那麼,這個值就是索引。
public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET;
public int numberOfMusicians() { return ordinal() + 1; } }
比如,int index = Ensemble.SOLO.ordinal(); 由於 SOLO 是列舉中的第一個值, 所以 index 的值為 0, numberOfMusicians() 方法意思是在索引的基礎上,又加了1。這樣寫有個壞處就是每個列舉型別對應的值不固定,如果在SOLO 之前再插入一個新的型別,那麼所有的列舉物件的 numberOfMusicians() 方法返回的值就都變了,如果以此為準做一些邏輯操作,需要用到索引值,則編譯 正確,執行正確,但邏輯結果卻不正確,並且還不好排查原因。列舉本身也想到了這一點,給出解決方案,就是增加一個屬性值
public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5), SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8), NONET(9), DECTET(10), TRIPLE_QUARTET(12);
private final int numberOfMusicians;
Ensemble(int size) { this.numberOfMusicians = size; }
public int numberOfMusicians() { return numberOfMusicians; } }
這樣,每一個列舉都有一個自己的值,再怎麼修改,都不會彼此影響其它物件,所以比較好用。所以還是用域值代替序數。
有一種情況可以直接使用序數,可以不用新增域值,寫起來也簡單。 程式碼中一般都會用到網路,那麼我們會寫一些網路地址,也會定義一些常量來對映地址,通常會把這些常量通過某種關係寫在一塊,這樣就很容易知道專案中用了哪些介面,呼叫網路介面,現在的網路框架一般都會給每個不同的介面標註一個唯一的值,作為拿到報文後資料,重新整理UI介面使用,重新整理介面的邏輯要和資料介面對應的上,這是後,我們可以把介面的名字統一用一個列舉來標識,唯一值就用ordinal()方法獲取,這時候裡面隨意修改位置都沒關係,因為我們只需要它們的值不同,都是唯一的就可以了。滿足類似這種情況的,我們可以用序數,否則還是要用例項域。