2015-08-19 52 views
3

如果你有一個Java enum和枚舉的類型的變量,像這樣:爲什麼Java需要EnumClass.VALUE而不是VALUE?

public enum Something 
{ 
    VAL1, 
    VAL2, 
    VAL3 
} 

public Something varName; 

爲什麼有必要寫varName = Something.VAL1;而不是簡單地varName = VAL1;?編譯器不應該知道varName的類型只能將null,VAL1,VAL2VAL3作爲值嗎?

+0

編號枚舉值不是全局的(除了在開關,它似乎)。 – Jashaszun

+0

如果'Something'實現了一個接口(例如'Serializable'),並且您想要將'varName'聲明爲'Serializable',那該怎麼辦?編譯器如何知道你正試圖從那個特定的枚舉中聲明,而不是其他任何可序列化的類型呢?該語言旨在允許將變量作爲其任何超類型進行輸入,並且這對使用您的建議枚舉聲明樣式是不可能的。 – Vulcan

回答

5

=語句的右邊是一個表達式,它通常被解析。總之,以顯示它如何複雜的編譯器,可以這樣考慮:

public enum Something { VAL1, VAL2, VAL3 } 

Something VAL3 = Something.VAL1; 

Something a = VAL3; 

應該a分配VAL1VAL3

你不需要枚舉名稱處於switch聲明,因爲case聲明必須使用有效的枚舉值唯一的一次,所以枚舉的名字是不必要的。

switch (a) { 
    case VAL1: 
     // do something 
     break; 
    case VAL2: 
     // do something 
     break; 
    case VAL3: 
     // do something 
     break; 
} 
+0

這是一個很好的觀點,並說得很清楚。我想,正如Ruahk在他的回答中所暗示的那樣,我並不討厭我的代碼的讀者,因爲這樣的結構甚至會讓我不知所措。 –

4

這是一個很好的問題。隨口說說,我能想到的唯一理由是,這樣的事情是完全有效的(前提是你最討厭的人閱讀你的代碼):

public class Evil { 
    public enum FooBar { FOO, BAR } 
    public static FooBar FOO = FooBar.BAR; 

    private FooBar baz = FOO; // means Evil.FOO, i.e. FooBar.BAR 
} 

的Java確實有一些類型推斷(例如,final List<String> emptyStringList = java.util.Collections.emptyList()相當於final List<String> emptyStringList = java.util.Collections.<String>emptyList() ,並且自從Java 5以來),但是這種類型推斷永遠不會改變表達式的含義,它只會爲其他含糊不清的表達式選擇單一含義。

+1

LOL喜歡討厭讀讀你的代碼的人。順便說一句:這是一種名爲「混淆」的編碼模式:https://en.wikipedia.org/wiki/Obfuscation_%28software%29 – Andreas

+0

一個很好的觀點,特別是討厭你的代碼的讀者。我從來沒有恨過他們,因爲這樣的結構甚至無法跨越我的想法。當然,我碰巧是我的代碼的主要讀者... –

1

如果您有兩個枚舉定義了VAL1,編譯器如何知道您指的是哪一個?

儘管如此,靜態進口可能使事情多一點可讀性:

import static Something.VAL1; 
+0

由類型,我會假設。當SomethingElse不從'Something'繼承時,將'Something'類型的變量設置爲'SomethingElse'類型的值是有效的。 –

0

沒有,永遠。在大多數情況下,如果所有範圍內的枚舉的所有範圍都自動打開,將解決模糊問題,但有一種情況可以打開一個枚舉的範圍:switch聲明:

Enum MyEnum 
{ 
    Value1; 
} 
MyEnum value = ...; 
switch (myEnumValue) 
{ 
case Value1: 
    // 
    break; 
} 
相關問題