我正在處理一些關於我使用某些不安全(無類型安全)的地方的一些工作,該模型的部分字符串或int表示。 並利用Enum和EnumSet最佳實踐。EnumSet <E>的最佳初始化E
一個特別的困難是這個用例:一個Enum,其中每個實例都擁有自己姐妹的[0..n]的EnumSet。
要剝離它的基本要點,我基於我的問題在Joshua Bloch StyleEnum。因此,我們得到了BOLD,ITALIC,UNDERLINE,STRIKETHROUGH的枚舉。讓我們想象一個B_AND_I,它將擁有{BOLD,ITALIC}。
請不要忽略這個毫無意義的例子:在真實系統中,這個子集是建立在啓動時加載的一些變化規則的基礎上的。
的目標是,一旦這種計算已經發生了,沒有什麼可以改變例如特定子EnumSet範圍。 所以我帶着這樣的:
public enum StyleEnum {
NONE(0, "none"), BOLD(100, "B"), ITALIC(250, "i"), UNDERLINE(350, "u"), STRIKETHROUGH(9, "b"), B_AND_I(99,"Emphase");
//// Pure dream == private final EnumSet<StyleEnum> complexComputedSubSet = new EnumSet<StyleEnum>();
//// But not in the jdk
private final EnumSet<StyleEnum> complexComputedSubSet;
private final int intProp;
private final String strLabel;
StyleEnum(int intProp, String strLabel) {
this.intProp = intProp;
this.strLabel = strLabel;
//// option 2 would have been be this
// complexComputedSubSet = EnumSet.of(NONE);
//// But COMPILER :: illegal reference to static field from initializer
}//.... end of constructor
/**
* static initialzer will compute based on some rules a subset of (none) or
* others Enum, a particular enum instance can holds in his bag.
*/
static {
//// at least, as option 3, why not this...
// for (StyleEnum e : EnumSet.allOf(StyleEnum.class)) {
// e.complexComputedSubSet = EnumSet.of(NONE);
// }
//// COMPILER :: cannot assign a value to final variable complexComputedSubSet
// main handling here : at class loading
// compute a set (rules coming from whatever you want or can).
//Once this static class level init is done
// nothing can change the computed EnumSet
// it's getter will always return an unmodifiable computed EnumSet
//.... computing something
}
//....
//getter(){}
//whateverelse(){}
}
正如你可以看到什麼是真正的愉快或至少優雅在這裏。
在我的夢想:
private final EnumSet<StyleEnum> complexComputedSubSet= new EnumSet<StyleEnum>();
//..
//static initialzer
static {
EnumSet.allOf(StyleEnum.class).forEach(e-> computeSubSet(e));
//..
}
private static void computeSubSet(StyleEnum instance){
//...
instance.complexComputedSubSet.addAll(someComputedCollection);
}
的Et瞧!
取而代之的是,我所能做的,似乎扯遠了最終場上
// getting away from the final keyword
private EnumSet<StyleEnum> complexComputedSubSet;
然後在theClass描述靜態初始化塊迴路上與(虛擬)標記(NONE)實例介紹了只爲這種(愚蠢的)目的:
for (StyleEnum e : EnumSet.allOf(StyleEnum.class)) {
e.complexComputedSubSet = EnumSet.of(NONE);
}
只有經過計算和儲存子EnumSet。
所以這一切的痛苦,-mostly-,只是因爲一個不能說「新的EnumSet();」 ? 必須有更好的方法嗎?你能指點我的好方向嗎?
不應該'e.complexComputedSubSet = EnumSet.copyOf(someComputedCollection);'就足夠了?你仍然需要刪除'final'關鍵字,但這不應該傷害。 – Thomas
順便說一句,我認爲'EnumSet.noneOf(StyleEnum.class)'應該是等同於'新EnumSet(); 「你在追求。 JavaDoc聲明:「用指定的元素類型創建一個空的枚舉集。」 - 該方法的名字很不幸,雖然:) –
Thomas
那是我第一次真正的attemps一個: '私人EnumSet complexComputedSubSet = EnumSet.noneOf(StyleEnum.class);' \t 但這個可愛的線在這可怕的跟蹤解析: \t **'所致:java.lang.ClassCastException:類entity.StyleEnum不是enum' ** '在java.util.EnumSet.noneOf(EnumSet.java:112)'' 在entity.StyleEnum。 (StyleEnum.java:22)'' 在entity.StyleEnum。 (StyleEnum。java:5)' \t 所以我剛剛退出它的使用。 –