2010-02-09 16 views
20

Sto guardando un codice Java che viene gestito da altre parti della società, tra l'altro alcuni ex sviluppatori C e C++. Una cosa che è onnipresente è l'uso di costanti intere statici, come ad esempioEnumerazioni Java rispetto a costanti statiche

class Engine { 
    private static int ENGINE_IDLE = 0; 
    private static int ENGINE_COLLECTING = 1; 
    ... 
} 

Oltre ad una carente qualificazione 'definitivo', sono un po 'infastidito da questo tipo di codice. Quello che mi sarebbe piaciuto vedere, in formazione soprattutto in Java da scuola, sarebbe qualcosa di più simile

class Engine { 
    private enum State { Idle, Collecting }; 
    ... 
} 

Tuttavia, gli argomenti mi mancano. Perché, se non del tutto, è quest'ultimo meglio del primo?

+4

+1 per rendere costanti 'final'. – uckelman

risposta

24

Perché, se non del tutto, è il secondo migliore rispetto al precedente?

È molto meglio perché offre sicurezza del tipo ed è auto-documentante. Con le costanti integer, devi consultare il documento API per scoprire quali valori sono validi e nulla ti impedisce di utilizzare valori non validi (o, forse peggio, costanti integer completamente indipendenti). Con Enum, la firma del metodo indica direttamente quali valori sono validi (il completamento automatico IDE funzionerà) ed è impossibile utilizzare un valore non valido.

I "interi enumerazioni costanti" modello è purtroppo molto comune, anche in Java API standard (e ampiamente copiato da lì) perché Java non ha avuto Enums prima di Java 5.

+3

+1 perché tu sei l'unico a citare l'autodocumentazione.Se hai un metodo, che accetta (o restituisce) un int, che rappresenta un codice, hai senza doc o sorgente nessuna possibilità di concludere alla semantica dell'int Ma l'enum ha un nome per ogni valore e la firma è direttamente (tramite tipo) connessa all'enum. – Mnementh

+1

+1 per "autodocumentazione" e "Il completamento automatico IDE funzionerà" –

0

Il primo è comune nel codice iniziato a 1.5. In realtà, un altro idioma comune era definire le costanti in un'interfaccia, perché non avevano alcun codice.

+0

Ma questa pratica incoraggia anche l'uso di ereditare quelle costanti, che è un po 'brutto. :( –

+0

@David: è l'ultimo dei problemi causati da "numero intero costante di enumerazioni" –

+0

@Michael: Ma un problema comunque –

5

Utilizzando un valore int per fare riferimento a una costante, non si sta costringendo qualcuno a utilizzare effettivamente tale costante. Così, per esempio, si potrebbe avere un metodo che prende uno stato del motore, a cui qualcuno potrebbe invocare soddisfatti:

engine.updateState(1); 

Utilizzando un enumforze all'utente di attaccare con l'etichetta esplicativa, quindi è più leggibile.

1

V'è una situazione in cui statica la costante è preferita (piuttosto che il codice è legacy con una tonnellata di dipendenza) e cioè quando il membro di quel valore non è/può in seguito non essere finito.

Immaginate se è possibile aggiungere un nuovo stato come Collected. L'unico modo per farlo con enum è quello di modificare il codice originale che può essere un problema se la modifica viene eseguita quando c'è già un sacco di codice che la manipola. Oltre a questo, personalmente non vedo alcun motivo per cui enum non venga usato.

Solo il mio pensiero.

+0

Tuttavia, l'aggiunta di un nuovo stato richiederebbe probabilmente altre modifiche nel codice (ovvero la gestione di tale nuovo stato). Quindi lo scenario non è molto probabile. Il codice legacy è probabilmente l'unico posto in cui questo approccio è appropriato. – Lajcik

1
  1. Readabiliy - Quando si utilizza enumerazioni e fare State.Idle, il lettore sa subito che si sta parlando di uno stato di inattività. Confronta questo con 4 o 5.

  2. tipologia di sicurezza - Quando l'uso enum, anche per errore l'utente non può passare un valore errato, come compilatore lo costringerà a utilizzare uno dei valori pre-dichiarato nella enum. In caso di numeri interi semplici, potrebbe persino passare -3274.

  3. Maintainability - Se si vuole aggiungere un nuovo stato Waiting, allora sarebbe molto facile aggiungere nuovo stato con l'aggiunta di un avviso di costante nel vostro Stato enum senza casuing alcuna confusione.
8

un estratto della documentazione ufficiale, http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html:

Questo modello ha molti problemi, come ad esempio:

  • Non typesafe - Dal momento che una stagione è solo un int è possibile passare in qualsiasi altro valore int dove è richiesta una stagione, o aggiungere due stagioni insieme (il che non ha senso).
  • Nessuno spazio dei nomi: è necessario prefisso le costanti di un int enum con una stringa (in questo caso SEASON_) per evitare conflitti con altri tipi di int enum.
  • Brittleness: poiché gli enumerati sono costanti in fase di compilazione, vengono compilati in client che li utilizzano. Se viene aggiunta una nuova costante tra due costanti esistenti o l'ordine viene modificato, i clienti devono essere ricompilati. Se non lo sono, funzioneranno comunque, ma il loro comportamento sarà indefinito.
  • I valori stampati non sono informativi: poiché sono solo inti, se ne stampi uno tutto ciò che ottieni è un numero, che non ti dice nulla di ciò che rappresenta, o anche di che tipo è.

E questo praticamente copre. Un argomento di una sola parola sarebbe che le enumerazioni sono solo più leggibili e istruttive.

Un'altra cosa è quell'enumerazione, come le classi. può avere campi e metodi. Questo ti dà la possibilità di includere alcune informazioni aggiuntive su ogni tipo di stato nell'enum stesso.

0

Enums offre anche una grande flessibilità. Poiché le enumerazioni sono essenzialmente classi, è possibile aumentarle con metodi utili (ad esempio fornire una stringa di risorse internazionalizzata corrispondente a un determinato valore nell'enumerazione, convertire avanti e indietro tra istanze del tipo enum e altre rappresentazioni che possono essere richieste, ecc.)

1

I motivi della specifica, che Lajcik cita, sono spiegati più dettagliatamente in Effective Java di Josh Bloch, Articolo 30. Se hai accesso a quel libro, ti consiglio di leggerlo. Le enumerazioni Java sono classi a pieno titolo, motivo per cui si ottiene la sicurezza del tipo in fase di compilazione. Puoi anche dare loro un comportamento, offrendoti un incapsulamento migliore.

Problemi correlati