2009-09-14 24 views
10

Cosa sono le enfasi Java? Come funzionano? Dove potrei usarli e come?
Posso fare senza usare enum in un'app o sono così potenti che è meglio usarli piuttosto che ignorarli?Informazioni su Enum in Java

risposta

40

Enums in Java 5+ sono fondamentalmente classi con un insieme predefinito di istanze. Sono intesi come una sostituzione per, diciamo, una raccolta di costanti intere. Preferibilmente sono costanti in quanto possono imporre la sicurezza del tipo.

Così, invece di:

public class Suit { 
    public final static int SPADES = 1; 
    public final static int CLUBS = 2 
    public final static int HEARTS = 3; 
    public final static int DIAMONDS = 4; 
} 

si hanno:

public enum Suit { 
    SPADES, CLUBS, HEARTS, DIAMONDS 
} 

I vantaggi sono:

  1. tipo di sicurezza. È possibile dichiarare un argomento di funzione, un tipo di ritorno, un membro della classe o una variabile locale come un particolare tipo Enum e il compilatore applicherà la sicurezza del tipo;
  2. Le enumerazioni sono fondamentalmente classi. Possono implementare interfacce, avere comportamenti e così via.

La sicurezza tipo è un problema perché nel primo esempio, queste sono le dichiarazioni valide:

int i = Suit.DIAMONDS * Suit.CLUBS; 

oppure si può passare da 11 a una funzione in attesa di un vestito. Non è possibile farlo con un enumerazione tipesa.

È possibile utilizzare una classe per Suit per fornire la sicurezza di tipo e questa era la soluzione prima di Java 5. Josh Bloch (in Effective Java, che è un deve leggere per i programmatori Java secondo me) promosso il modello typesafe enum che è diventato il Java 5+ enum. Ha una buona dose di codice e alcuni casi d'angolo che le persone non tendono a soddisfare, come la serializzazione che non chiama un costruttore e per assicurarti di avere solo un'istanza devi sovrascrivere il metodo readResolve().

Ad esempio:

public enum CardColour { 
    RED, BLACK 
} 

public enum Suit { 
    SPADES(CardColour.BLACK), 
    CLUBS(CardColour.BLACK), 
    HEARTS(CardColour.RED), 
    DIAMONDS(CardColour.RED); 

    private final CardColour colour; 

    Suit(CardColour colour) { this.colour = colour; } 

    public CardColour getColour() { return colour; } 
} 

Edit: Sun ha un introduction to typesafe enums.

Per quanto riguarda le interfacce, completano davvero le enumerazioni anziché essere un'alternativa. Come si potrebbe dire che il vestito è un'interfaccia e che avresti avuto questo:

public interface Suit { 
    CardColour getColour(); 
} 

Il problema è che si poteva andare e definire 300 semi diversi e si potrebbe anche definire Spades più volte. Un altro vantaggio dell'enumerazione è (nonostante il caso di classloading corner) è che esiste una sola istanza di ciascun valore enum.In genere questo si riferisce a come avere un valore canonico , che significa questa uguaglianza vale:

a.equals(b) == b.equals(a) == (a == b) 

per tutti a, b che sono istanze di un particolare Enum. Ciò significa che invece di scrivere:

if (card.getSuit().equals(Suit.SPADES)) { ... } 

si può scrivere:

if (card.getSuit() == Suit.SPADES) { ... } 

, che è più veloce e in genere più facile da leggere. In genere, gli IDE ti danno un feedback se stai confrontando enumerazioni di tipi diversi dicendo che non possono essere uguali, il che può essere una forma utile e precoce di controllo degli errori.

+1

Sun's Guide (http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html) offre una buona visione del loro potenziale; Suggerirei di aggiungere un riferimento per ulteriori letture. –

+0

@cletus ... non è possibile utilizzare un'interfaccia per lo stesso? –

+0

@cletus: non ho capito la parte "sicurezza del tipo" di esso. Non una classe Java fornisce sicurezza di tipo? –

1

Sun's enum documentation è probabilmente la migliore spiegazione. Ovviamente si può fare a meno di loro, come hanno fatto sicuramente i programmatori Java fino al rilascio di Java 1.5. Normalmente si ottiene la stessa cosa usando le costanti nelle versioni di Java precedenti alla 1.5. Ma le enumerazioni sono una buona comodità.

+0

Perché è stato inclusi in Java 1.5? È così potente? –

1

Se la situazione non si presenta, non ne hai bisogno.

Essi consentono di avere una serie ben definita di cose, per esempio se si voleva rappresentare gli stati della materia si potrebbe avere:

enum MatterState { 
    Solid, 
    Liquid, 
    Gas; 
} 

Dove hanno battuto il vecchio stile di utilizzare oggetti per rappresentare set in un certo numero di modi, alcuni dei quali sono:

  • È possibile utilizzarli nelle istruzioni dell'interruttore .
  • Meno codice.
  • Costruito in da/per stringa.
+0

mi hai battuto per rispondere usando l'esatto esempio;) – n002213f

+3

dimenticato Plasma: p –

0

Dalla mia interpretazione, le enumerazioni sono più di leggibilità che altro. Fondamentalmente sono usati per sostituire valori come 1-6 con nomi più descrittivi, come [Happy, Sad, Angry, ecc.] Dovresti usarli ogni volta che devi usare un piccolo set di variabili per descrivere la soluzione che stai aspettando.

+2

@bogerton: in realtà, ci sono significativi vantaggi di tipesafety nell'usare enumerazioni Java; vedi l'eccellente risposta di @ cletus. –

11

Pensate Enum come segue

public class MyEnum { 

    // Object instantiated at declaration 
    public static final MyEnum ONE = new MyEnum(); 
    public static final MyEnum TWO = new MyEnum(); 
    public static final MyEnum THREE = new MyEnum(); 

    // Notice a private constructor 
    // There is no way outside MyEnum class call it 
    private MyEnum() { ... } 


} 

Quindi un MyEnum come enum sarebbe

public enum MyEnum { 
    ONE, 
    TWO, 
    THREE; 
} 

Entrambi sono simili

saluti,

1

Per aggiungere alcune informazioni aggiuntive per scoprilo di più, è meglio iniziare dal concetto di una variabile e dai suoi valori. Come sono sicuro che tu ora, ogni variabile ha un tipo dichiarato (come i tipi primitivi di Java). Ogni tipo ha i suoi valori corrispondenti. Ad esempio, una variabile con il tipo di carattere può accettare tutti i singoli caratteri come valori. Quindi è molto utile quando si desidera dichiarare una variabile in grado di accettare tutto il set di costanti di caratteri. Per esempio tutte le costanti carattere sono accettabili e significativo per la variabile aCharToStopProgram:

char aCharToStopProgram = getUserInput(); 

Tuttavia, che dire quando si ha un valore limitato, voglio dire il dominio di valore della variabile è limitato a valori speciali. Ad esempio hai userChoice che mantiene il valore della domanda a scelta multipla del sistema. Quindi solo 'a', 'b', 'c', 'd' è significativo. Non si desidera in un'altra sezione del codice del programma (o per altri motivi) questa variabile viene assegnata con valori privi di significato come "s".Ora è vero che per la nostra variabile si usa un tipo di carattere primitivo che può accettare qualsiasi costante di carattere, come segue.

char userChoice = getUserChoice(); 

In questo caso, Java fornisce tipi enumerati. Significa che tramite la parola chiave enum puoi definire una nuova classe che ha istanze limitate e fisse chiamate valori con nome (non puoi creare nuovi oggetti). Per esempio:

enum MultipleChoiceAnswer { A, B, C, D }; 

o

public enum MultipleChoiceAnswer { 

    A('a'), B('b'), C('c'), D('d'); 

    private char choice; 

    private MultipleChoiceAnswer(char choice) { 
     this.choice = choice; 
    } 

    public String getChoice() { 
     return choice; 
    } 
} 

Come risultato si può definire una variabile con il proprio tipo:

MultipleChoiceAnswer userChoice = getUserChoice();//OR MultipleChoiceAnswer.A