En Java, un Enum puede hacer las grandes cosas que hacen los Enum, pero también puede tener métodos (comportamiento y lógica). ¿Qué ventaja tiene eso sobre usar una clase usando una enumeración? Ejemplos simples para ilustrar el punto también serían bienvenidos.Java Enums puede tener comportamiento?
Respuesta
Aquí está un ejemplo sencillo:
enum RoundingMode {
UP {
public double round(double d) {
return Math.ceil(d);
}
},
DOWN {
public double round(double d) {
return Math.floor(d);
}
};
public abstract double round(double d);
}
No estoy muy seguro de dónde encaja el título de la pregunta con el resto. Sí, las enumeraciones Java tienen comportamiento. También pueden tener estado, aunque en realidad debería ser realmente estado inmutable. (La idea de un valor enum mutable es bastante aterradora IMO.)
Una enumeración en Java es básicamente un conjunto fijo de objetos. El beneficio es que usted sabe que si tiene una referencia de ese tipo, es siempre ya sea null
o uno de los conjuntos conocidos.
Personalmente, me encantan las enums de Java y deseo que C# las tuviera también; están mucho más orientadas a objetos que las enumeraciones de C# que son básicamente "números con nombre". Hay algunos "errores" en términos de orden de inicialización, pero en general son fabulosos.
¿No puedes emular las enumeraciones de Java con clases de C#? –
@Vilx: por supuesto que puedes. Antes de Java 5, podría escribir sus propias clases para hacer objetos enum de tipo seguro. (Bueno, todavía puedes, por supuesto, no hay mucho de un punto.) – Eddie
Vilx: Puedes, pero es un poco desagradable. Básicamente se usa un tipo base abstracto con un constructor privado, y se deriva de él con tipos * anidados * que pueden llamar al constructor privado. –
En nuestro proyecto, usamos Enums para algunas cosas, pero quizás lo más destacado para i18n, cada parte del texto mostrado tiene un Enum. La clase Enum tiene un método de devolución de cadena que inspecciona la configuración regional que se está utilizando y selecciona la traducción correcta de una colección de traducciones en tiempo de ejecución.
Esto tiene un doble propósito: obtiene el código completo de su IDE y nunca se olvida de traducir una cadena.
El uso es muy simple, hasta el punto de que es casi rendundant para dar un ejemplo, pero aquí es cómo se puede utilizar la traducción-enumeración
System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());
O, si se quiere ser de lujo, tiene la Enum aceptar los argumentos, que, con un poco de manipulación de cadenas magia, pueden insertar en una posición marcada en la cadena de traducciones
System.out.println(Translations.GREET_PERSON.trans(user.getName());
Interesante uso, pero parece que podría obtener el mismo comportamiento de una serie de métodos estáticos en una clase. Supongo que no veo la ventaja de usar la enumeración. – Dave
Los comentarios son mucho más fáciles de agregar cuando es necesario. También son conscientes de sí mismos: puede obtener la cadena de la enumeración dentro de trans(), por lo tanto, puede usar eso como una palabra clave para hacer coincidir en su tabla de traducciones –
Los tipos Enum
también son una excelente manera de implementar singletons verdaderos.
Los patrones de singleton clásicos en Java normalmente implican constructores privados y métodos públicos de fábrica estáticos, pero aún son vulnerables a la creación de instancias mediante reflexión o (des) serialización. Un tipo enum protege contra eso.
Aunque obtienes algún método extraño "gratis". (De todos modos los singletons son malos.) –
No entiendo el comentario. –
Punto de interés. ¿Cómo protege el enum contra la reflexión y la deserialización? Supongo que estoy preguntando, ¿qué es lo que realmente me impide crear una enumeración a través de la reflexión? ¿El compilador lanza una excepción marcada? – Dave
Dado que las instancias enum son singletons, puede usarlas en las declaraciones switch
o con ==
para verificar la igualdad.
Básicamente, las enumeraciones de Java son clases (no creo que haya una diferencia en el nivel de bytecode), con la ventaja adicional de tener un conjunto fijo de posibles instancias conocidas y ser capaces de usarlas en instrucciones de conmutación .
Puede emular el "conocido conjunto fijo de instancias posibles" con clases regulares (el patrón "ensafe seguro" descrito en innumerables libros y artículos), pero es bastante trabajo (repetido para cada clase) obtenerlo funciona realmente correctamente con respecto a Serialization, equals() y hashCode(), y tal vez algunas otras cosas que olvidé. Las enumeraciones de nivel de idioma le evitan ese trabajo. Y, como se mencionó anteriormente, solo las enumeraciones de nivel de idioma se pueden usar en instrucciones de cambio.
Son clases, pero hay una diferencia en el nivel de bytecode. Por un lado, las clases enum tienen el indicador ACC_ENUM. Ver http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf. –
Eche un vistazo a las clases de tiempo de java/joda, donde las enumeraciones hacen muchísimo trabajo.
Aquí es un ejemplo de java.time.Month:
public enum Month implements TemporalAccessor, TemporalAdjuster {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
private static final Month[] ENUMS = Month.values();
public static Month of(int month) {
if (month < 1 || month > 12) {
throw new DateTimeException("Invalid value for MonthOfYear: " + month);
}
return ENUMS[month - 1];
}
// About a dozen of other useful methods go here
}
- 1. Ampliación de Java Enums
- 2. Deberían los enums tener valores no inicializados.
- 3. enums de Java ordenando
- 4. ¿Es posible extender Java Enums?
- 5. ¿Utiliza enums de Java de diferentes clases?
- 6. Uso de Java Generics con Enums
- 7. Java Enums: Implementing methods After Declaration?
- 8. ¿Cuántos caracteres puede tener Java String?
- 9. deserializing enums
- 10. Diseño pitónico sin enums
- 11. C# Enums and casting
- 12. Extraño comportamiento de NumberFormat Java
- 13. Espacios en C# Enums
- 14. WCF Versioning Enums
- 15. ¿puede declararse C# enums como de tipo bool?
- 16. Sugerencia de codificación: tipos de intersección y enums Java
- 17. ¿Puede una Java Enum tener más de un constructor?
- 18. ¿Puede un archivo Java tener más de una clase?
- 19. ¿Por qué PriorityQueue en Java no puede tener initialCapacity 0?
- 20. dapper nuget 1.7 enumeración enums
- 21. extraño comportamiento de Java operador + =
- 22. comportamiento fallido de java HashMap
- 23. 64bit Enums? C#
- 24. Interfaces vs. enums
- 25. DataContractJsonSerializer y Enums
- 26. ¿Puedo comparar enums de MySQL?
- 27. Comportamiento de ScheduledExecutorService.scheduleAtFixedRate de Java()
- 28. Java UTF-8 comportamiento extraño
- 29. comportamiento extraño de == en Java
- 30. Java comportamiento operación de multiplicación
¿Cómo usaría esto en el código? ¿Acabo de hacer esto? double foo = RoundingMode.round (20.3); ¿O ampliaría la enumeración a la enumeración de hijo? Me abandona el método abstracto. – Dave
El método abstracto es anulado por las clases anidadas usadas por UP y DOWN. Lo usarías en un código como este: double doMath (RoundMode m, double x, double y) {double d; ... d = m.round (d); ... devolver d; } Pasarías en RoundingMode.UP o RoundingMode.DOWN como el primer parámetro. –
¡Gracias! No estoy seguro de cómo me siento al respecto, pero ahora lo entiendo;) – Dave