2013-01-04 18 views
14

Ho un ente che ha una proprietà enum:utilizzando enum in switch/case

// 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; 
    } 
} 

Voglio salvare questa entità nel database e recuperarlo. Il problema è che io salvo il valore int nel database e ottengo un valore int! Non posso usare l'interruttore come di seguito:

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

Cosa devo fare?

+0

potrebbe essere il caso peggiore, ma solo la soluzione che posso vedere è usare un getter diverso estendendo la classe che restituisce valore come enum. –

risposta

26

Si potrebbe fornire un metodo statico nella vostra enum:

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

Poi nel codice principale:

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

Il vantaggio di questo approccio rispetto al numero ordinale, è che sarà ancora funzionare se le modifiche enum a qualcosa di simile:

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

Si noti che l'implementazione iniziale del getStatusFromInt potrebbe utilizzare la proprietà ordinali, ma quel dettaglio di implementazione è ora incluso nella classe enum.

11

Ogni enum Java ha un ordinale che viene assegnato automaticamente, quindi non è necessario specificare manualmente l'int (ma essere consapevoli che gli ordinali iniziano da 0, non 1).

Quindi, per ottenere la vostra enum dalla ordinale, si può fare:

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

... allora si può fare lo switch utilizzando l'enumerazione ...

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

"..., quindi non è necessario specificare manualmente l'int ..." <--- Questo NON è vero quando è necessario comunicare con altri software (di terze parti) o macchine che hanno numeri interi fissi per un determinato interfaccia (es. tipo di messaggio)! – user504342

+0

@ user504342: Il punto di questa risposta è che un enum contiene già un ordinale e quindi, se il tuo caso d'uso ti consente di fare affidamento su questo, puoi senza dover fare altro. Se non puoi usare l'ordinale perché devi conformarti ad uno schema esistente, allora la risposta di [assylias] (http://stackoverflow.com/a/14154869/1212960) copre questo. –

+0

\ @GregKopff: mi dispiace non essere d'accordo. Secondo il libro di Joshua Bloch Effective Java (2a ed.) NON dovresti fare affidamento sui valori ordinali. Vedere l'articolo 31 che indica chiaramente: "Non derivare mai un valore associato a un enum dal suo ordinale, ma memorizzarlo in un campo di istanza". Il libro spiega in dettaglio perché è così. – user504342