2014-10-12 64 views
3

我知道在Java中一個enum常量是隱含的static final變量。但enum類可以有一個實例變量say大小。所以每個enum常量都會有一個'size'的副本。 這是什麼等效的Java代碼?我的意思是「似乎」靜態enum常量是使用非靜態的實例變量,這是不可能正常?java如何支持java枚舉常量的實例變量?

enum Members{ 
    A(1),B(2),C(3); // I have 3 enum constants here 

    private int size; 
    Members (int size) { 
     //System.out.println("Initializing var with size = "+size); 
    } 
} 

等效代碼我知道到目前爲止:

public final class Member extends Enums<Members> { 
    public static final Members A; 
    // ... 
    // What happened to size? How do A,B,C get a copy of size? 
} 

編輯:要重申我question- 我感興趣的由編譯器執行的場景背後。我已經知道如何使用枚舉。我正在尋找編譯器的功能? (例如,如果我簡單地寫A,編譯器將其翻譯爲「公共靜態最終成員A」。我想知道編譯器如何給每個A,B,C一個大小的副本。

+0

不要混淆變量和引用與對象。 – 2014-10-12 14:51:14

回答

3

我的意思是「似乎」靜態枚舉常量是使用非靜態的實例變量,這是不可能正常?

這是絕對可能的:在每個enum變量static是在自己的權利的對象,完成它的實例變量。enum中的實例爲static,但它不會使實例本身的上下文成爲靜態上下文。

public final class Member extends java.lang.Enums<Members> { 
    public static final Members A = new Member(1) { 
     public String toString() { return "A:"+size; } 
    }; 
    public static final Members B = new Member(2) { 
     public String toString() { return "B:"+size; } 
    }; 
    public static final Members C = new Member(3) { 
     public String toString() { return "C:"+size; } 
    }; 
    private final int size; 
    protected Member(int size) { this.size = size; } 
} 
+1

爲什麼要創建一個新的每個'成員'變量的類? – msrd0 2014-10-12 14:51:48

+0

所以你在說什麼是每個枚舉常量A,B,C得到一個大小的副本,所以Java接受我的代碼並將它轉換爲類似的東西(爲A創建一個實例var,for B等),這意味着編譯器正在做一些幕後的事情,我正在尋找幕後的東西 – rents 2014-10-12 15:38:36

+0

我的意思是「通常」是非枚舉類中的靜態變量不能訪問非靜態變量 – rents 2014-10-12 15:40:09

2

I意思是「似乎」靜態枚舉常量使用非靜態實例變量,這是不可能正常嗎?

我的意思是「通常」是非枚舉類靜態變量不能訪問非靜態變量

仍然是這樣:靜態變量不能訪問非靜態變量 在你的示例代碼中,你不這樣做這個: 沒有靜態變量訪問非靜態變量。

構造函數Members(int size)不在靜態上下文中(構造函數永遠不會)。 A,B和C都是枚舉類型Members, 的所有實例,並且在創建這些實例時,將使用參數size調用構造函數。 一旦構建,這些對象將被視爲靜態常量值。

也許另一個例子可以幫助:

class Person { 
    private final String name; 
    Person(String name) { 
     this.name = name; 
    } 
} 
class EmployeeDatabase { 
    private static final Person CEO = new Person("Jack"); 
} 

這裏EmployeeDatabase.CEO是與非靜態字段name靜態常量對象。 這就像Members.A,一個帶有非靜態字段size的靜態常量對象。

我想知道編譯器如何給每個A,B,C一個大小的副本。

與將構造函數參數傳遞給任何對象的方式完全相同。

你可以閱讀所有關於docs中的枚舉。

+0

這不會編譯,'size'不能是最終的 – msrd0 2014-10-12 14:46:01

+0

當然可以。它不僅可以是最終的,它應該是最終的。一個可變的枚舉將是非常薄弱的​​設計。 – janos 2014-10-12 14:47:22

+0

如果您有一個未初始化的final變量,那麼不會顯示錯誤消息嗎?當一個'final'變量在ctor中初始化時? – msrd0 2014-10-12 14:49:27