2009-09-14 30 views
10

¿Qué son las enums de Java? ¿Cómo trabajan? ¿Dónde podría usarlos y cómo?
¿Puedo prescindir de utilizar enumeraciones en una aplicación o son tan poderosas que es mejor usarlas que ignorarlas?Comprender enumeraciones en Java

Respuesta

40

Las enumeraciones en Java 5+ son básicamente clases que tienen un conjunto predefinido de instancias. Están pensados ​​como un reemplazo para, por ejemplo, una colección de constantes enteras. Son preferiblemente constantes ya que pueden hacer cumplir la seguridad del tipo.

Así que en lugar de:

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

tiene:

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

Las ventajas son:

  1. Seguridad de tipos. Puede declarar que un argumento de función, tipo de retorno, miembro de clase o variable local es un tipo particular de Enum y el compilador aplicará seguridad de tipo;
  2. Las enumeraciones son básicamente clases. Pueden implementar interfaces, tener comportamiento, etc.

La seguridad de tipos es un problema porque en el primer ejemplo, se trata de afirmaciones válidas:

int i = Suit.DIAMONDS * Suit.CLUBS; 

o puede pasar en 11 a una función que espera un traje. No puedes hacer eso con una enumeración segura de tipos.

Puede utilizar una clase de traje para proporcionar la seguridad de tipos y esta fue la solución antes de Java 5. Josh Bloch (en Effective Java, que es una lectura obligada para los programadores de Java mi humilde opinión) promovieron el patrón de seguridad de tipos de enumeración que se convirtió en el Enum de Java 5+. Tiene una buena cantidad de texto estándar y algunos casos de esquina que las personas no tienden a atender, como la serialización que no llama a un constructor y para asegurarse de que solo tiene una instancia, debe anular el método readResolve().

Por ejemplo:

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

Editar: Sol tiene una introduction to typesafe enums.

En cuanto a las interfaces, realmente complementan las enumeraciones en lugar de ser una alternativa. Al igual que se podría decir que el juego es una interfaz y que tendría esto:

public interface Suit { 
    CardColour getColour(); 
} 

El problema es que se puede ir y definir 300 trajes diferentes y también se podría definir Picas varias veces. Otra ventaja de las enumeraciones es (a pesar de casos de esquina de carga de clases) es que solo hay una instancia de cada valor enum.Normalmente, esto se conoce como que tiene un valor canónica, es decir, esta igualdad es válido:

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

para todo a, b que son instancias de un Enum particular. Esto significa que en lugar de escribir:

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

puede escribir:

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

que es más rápido y por lo general más fáciles de leer. Además, los IDE generalmente le darán retroalimentación si compara enums de diferentes tipos diciendo que no pueden ser iguales, lo que puede ser una forma útil y temprana de comprobación de errores.

+1

Sun's Guide (http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html) ofrece una buena visión de su potencial; Sugeriría agregar una referencia para leer más. –

+0

@cletus ... ¿no se podría usar una interfaz para lo mismo? –

+0

@cletus: No entendí la parte del "tipo de seguridad". ¿Una clase Java no proporciona seguridad de tipo? –

1

Sun enum documentation es probablemente la mejor explicación. Por supuesto, puede prescindir de ellos, ya que los programadores de Java ciertamente lo hicieron hasta que se lanzó Java 1.5. Por lo general, se lograría lo mismo mediante el uso de constantes en las versiones de Java anteriores a la 1.5. Pero las enumeraciones son una buena conveniencia.

+0

¿Por qué se incluyó en Java 1.5? ¿Es tan poderoso? –

1

Si la situación no aparece, entonces no las necesita.

Ellos le permiten tener un conjunto bien definido de las cosas, por ejemplo, si desea representar los estados de la materia que podría tener:

enum MatterState { 
    Solid, 
    Liquid, 
    Gas; 
} 

donde vencieron el viejo estilo de la utilización de objetos para representar conjuntos de varias maneras, algunas de las cuales son:

  • Puede usarlas en las declaraciones switch .
  • Menos código.
  • Construido en a/desde cadena.
+0

me ganaste a contestar usando el ejemplo exacto;) – n002213f

+3

se olvidó de Plasma: p –

0

Desde mi interpretación, las enumeraciones son más para la legibilidad que cualquier otra cosa. Básicamente se utilizan para reemplazar valores como 1-6 con nombres más descriptivos, como [Feliz, Triste, Enojado, etc.] Debe usarlos cada vez que necesite usar un pequeño conjunto de variables para describir la solución que está esperando.

+2

@bogerton: en realidad, existen ventajas significativas de seguridad para el uso de las enumeraciones de Java; ver la excelente respuesta de @ cletus –

11

Piense en Enumeración de la siguiente manera

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() { ... } 


} 

Así que un MyEnum como una enumeración sería

public enum MyEnum { 
    ONE, 
    TWO, 
    THREE; 
} 

Ambos son similares

respecto,

1

Para añadir alguna información adicional para descubra más, es mejor comenzar con el concepto de una variable y sus valores. Como estoy seguro de que ahora, cada variable tiene un tipo declarado (como los tipos primitivos de Java). Cada tipo tiene sus propios valores correspondientes. Por ejemplo, las variables con el tipo de caracteres pueden aceptar todos los caracteres individuales como sus valores. Por lo tanto, es muy útil cuando quiere declarar que una variable puede aceptar todo el conjunto de constantes de caracteres. Por ejemplo todas las constantes de caracteres son aceptables y significativa para la variable aCharToStopProgram:

char aCharToStopProgram = getUserInput(); 

Sin embargo, ¿qué pasa cuando se tiene un valor limitado, es decir el dominio del valor de la variable se limita a valores especiales. Por ejemplo, tiene userChoice que mantiene el valor de la pregunta de opción múltiple del sistema. Entonces 'a', 'b', 'c', 'd' son significativos. No desea en otra sección de su código de programa (o cualquier otra razón) esta variable está asignada con valores sin sentido como 's'.Ahora es cierto usar un tipo primitivo de caracteres para nuestra variable, que puede aceptar cualquier constante de caracteres, como la siguiente.

char userChoice = getUserChoice(); 

En esta situación, Java proporciona tipos enumerados. Significa que a través de la palabra clave enum puede definir una nueva clase que tenga instancias limitadas y fijas, que es llamada llamada valores (no puede crear nuevos objetos). Por ejemplo:

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

Como resultado se puede definir una variable con su propio tipo:

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