2013-01-04 69 views
14

我有了一個枚舉屬性的實體:使用枚舉在開關/箱

// MyFile.java 
public class MyFile { 
    private DownloadStatus downloadStatus; 
    // other properties, setters and getters 
} 

// DownloadStatus.java 
public enum DownloadStatus { 
    NOT_DOWNLOADED(1), 
    DOWNLOAD_IN_PROGRESS(2), 
    DOWNLOADED(3); 

    private int value; 
    private DownloadStatus(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return value; 
    } 
} 

我要保存在數據庫中這個實體和檢索。問題是我保存在數據庫中的int值,我得到int值!我不能使用如下的開關:

MyFile file = new MyFile(); 
int downloadStatus = ... 
switch(downloadStatus) { 
    case NOT_DOWNLOADED: 
    file.setDownloadStatus(NOT_DOWNLOADED); 
    break; 
    // ... 
}  

我該怎麼辦?

+0

可能是多數民衆贊成在最壞的情況下,但唯一的解決辦法是我可以使用一個不同的getter通過擴展類,返回值作爲枚舉。 –

回答

26

你可以提供在枚舉了一個靜態方法:

public static DownloadStatus getStatusFromInt(int status) { 
    //here return the appropriate enum constant 
} 

然後在你的主代碼:

int downloadStatus = ...; 
DowloadStatus status = DowloadStatus.getStatusFromInt(downloadStatus); 
switch (status) { 
    case DowloadStatus.NOT_DOWNLOADED: 
     //etc. 
} 

這與序方法的優點是,它仍會如果枚舉的變化工作是這樣的:

public enum DownloadStatus { 
    NOT_DOWNLOADED(1), 
    DOWNLOAD_IN_PROGRESS(2), 
    DOWNLOADED(4);   /// Ooops, database changed, it is not 3 any more 
} 

注意,初步實現了getStatusFromInt的可能使用的順序屬性,但是該實現細節現在被包含在枚舉類中。

11

每個Java枚舉都有一個自動分配的序號,因此您不需要手動指定int(但要注意,序數從0開始,而不是1開始)。

然後,您可以通過有序的枚舉,你可以這樣做:

int downloadStatus = ... 
DownloadStatus ds = DownloadStatus.values()[downloadStatus]; 

...那麼你可以用枚舉做你的開關......

switch (ds) 
{ 
    case NOT_DOWNLOADED: 
    ... 
} 
+0

「,因此您不需要手動指定int ...」<---當您需要與其他(第三方)軟件或具有固定整數的機器進行通信時,這不是真的界面(例如消息類型)! – user504342

+0

@ user504342:這個答案的重點在於枚舉已經包含一個序號,所以如果你的用例允許你依賴that_,你可以不需要做更多的事情。如果因爲必須符合某些現有方案而無法使用序號,那麼[assylias的答案](http://stackoverflow.com/a/14154869/1212960)涵蓋了這一點。 –

+0

\ @GregKopff:抱歉不同意。根據Joshua Bloch的書籍Effective Java(2nd ed。),你不應該依賴序數值。請參閱第31項,其中明確指出:「永遠不要從枚舉的枚舉中獲取與其相關的值;將其存儲在實例字段中」。這本書詳細解釋了這是爲什麼。 – user504342