Varias veces he visto a personas usar el título de mayúsculas o incluso todos los nombres en minúsculas para constantes de enumeración, por ejemplo:
enum Color {
red,
yellow,
green;
}
Esto hace que trabajar con su forma de cadena sea simple y fácil, si lo desea throw new IllegalStateException("Light should not be " + color + ".")
, por ejemplo.
Esto parece más aceptable si la enumeración es private
, pero todavía no me gusta. Sé que puedo hacer un constructor enum con un campo String y luego anular toString para devolver ese nombre, así:
enum Color {
RED("red"),
YELLOW("yellow"),
GREEN("green");
private final String name;
private Color(String name) {
this.name = name
}
@Override public String toString() {
return name;
}
}
Pero mira cuánto tiempo más es eso. Es molesto seguir haciéndolo si tienes un montón de enumeraciones pequeñas que quieres que sean simples. ¿Está bien usar formatos de caso no convencionales aquí?
java
conventions
enum
descifrador de códigos
fuente
fuente
Light should not be RED.
. Después de todo, este mensaje es para el desarrollador, el usuario nunca debería verlo.Light should not be YELLOW.
, supongo que es una constante de algún tipo, el método toString () es solo para fines de depuración, por lo que no veo por qué necesita cambiar la apariencia de ese mensaje.Respuestas:
La respuesta corta es, por supuesto, si desea romper con las convenciones de nomenclatura para lo que son esencialmente constantes ... Citando del JLS :
La respuesta larga, con respecto al uso de
toString()
, es que definitivamente es el método para anular si desea una representación más legible de losenum
valores. Citando deObject.toString()
(énfasis mío):Ahora, no estoy seguro de por qué algunas de las respuestas derivaron a hablar de convertir de aquí
enums
para allá conString
valores, pero también daré mi opinión aquí. Dicha serialización deenum
valores se puede solucionar fácilmente utilizando los métodosname()
oordinal()
. Ambos sonfinal
y, por lo tanto, puede estar seguro de los valores devueltos siempre que los nombres o la posición de los valores no cambien . Para mí, ese es un marcador lo suficientemente claro.Lo que deduzco de lo anterior es: hoy, es posible que desee describir
YELLOW
como simplemente "amarillo". Mañana, es posible que desee describirlo como "Pantone Minion Yellow" . Estas descripciones deben ser devueltos a llamartoString()
, y yo no espero dename()
oordinal()
al cambio. Si lo hago, eso es algo que necesito resolver dentro de mi base de código o mi equipo, y se convierte en una pregunta más importante que solo unenum
estilo de nomenclatura .En conclusión, si todo lo que pretende hacer es registrar una representación más legible de sus
enum
valores, aún le sugiero que se adhiera a las convenciones y luego anuletoString()
. Si también tiene la intención de serializarlos en un archivo de datos o en otros destinos que no sean Java, todavía tiene los métodosname()
yordinal()
para respaldarlo, por lo que no hay necesidad de preocuparse por anularlostoString()
.fuente
No modifique
ENUM
eso es solo un mal olor del código. Deje que una enumeración sea una enumeración y una cadena sea una cadena.En su lugar, use un convertidor CamelCase para valores de cadena.
Hay muchas bibliotecas de código abierto que ya resuelven este problema para Java.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CaseFormat.html
fuente
Al enviar enumeraciones entre mi código Java y una base de datos o aplicación cliente, a menudo termino leyendo y escribiendo los valores de enumeración como cadenas.
toString()
se llama implícitamente al concatenar cadenas. Anular toString () en algunas enumeraciones significaba que a veces solo podíay a veces tenía que recordar llamar
lo que condujo a errores, así que ya no hago eso. En realidad, no anulo ningún método en Enum porque si los aplica a un código de cliente suficiente, eventualmente romperá las expectativas de alguien.
Haga su propio nombre de método nuevo, como
public String text()
otoEnglish()
o lo que sea.Aquí hay una pequeña función auxiliar que podría ahorrarle algo de escritura si tiene muchas enumeraciones como la anterior:
Siempre es fácil llamar a .toUpperCase () o .toLowerCase (), pero recuperar mayúsculas y minúsculas puede ser complicado. Considere el color, "bleu de France". Francia siempre está en mayúscula, por lo que es posible que desee agregar un método textLower () a su enumeración si se encuentra con eso. Cuando usa este texto al comienzo de una oración, frente a la mitad de una oración, frente a un título, puede ver cómo un solo
toString()
método se quedará corto. Y eso ni siquiera toca caracteres que son ilegales en los identificadores de Java, o que son difíciles de escribir porque no están representados en teclados estándar, o caracteres que no tienen mayúsculas (Kanji, etc.).No es tan difícil usarlos correctamente:
Esperemos que eso también demuestre por qué el uso de valores de enumeración de mayúsculas y minúsculas también lo decepcionará. Una última razón para mantener todo en mayúsculas con constantes enum de subrayado es que hacerlo sigue el Principio de Menos Asombro. La gente lo espera, así que si haces algo diferente, siempre tendrás que explicarte a ti mismo o tratar con personas que usen mal tu código.
fuente
toString()
una enumeración no tiene sentido para mí. Si desea el comportamiento predeterminado garantizado de los nombres de enumeración, usename()
. No me parece "tentador" en absoluto confiartoString()
para proporcionar la clave correctavalueOf(String)
. Supongo que si quieres probar tus enumeraciones a prueba de idiotas, eso es una cosa, pero no creo que sea una razón suficiente para recomendarte que nunca debas anulartoString()
.<input type='checkbox' value=" + MY_CONST1 + ">
, y a veces tenía que acordarme de llamar<input type='checkbox' value=" + MY_CONST1.name() + ">
, lo que provocaba errores.Si existe la más mínima posibilidad de que estas representaciones de cadenas se almacenen en lugares como bases de datos o archivos de texto, entonces vincularlas con las constantes de enumeración reales será muy problemático si alguna vez necesita refactorizar su enumeración.
¿Qué pasa si un día se decide cambiar el nombre
Color.White
aColor.TitaniumWhite
bien hay datos que contienen archivos por ahí "blanca"?Además, una vez que comience a convertir constantes de enumeración en cadenas, el siguiente paso más adelante será generar cadenas para que el usuario las vea, y el problema aquí es, como estoy seguro de que ya sabe, que la sintaxis de Java no permitir espacios dentro de los identificadores. (Nunca lo habrá hecho
Color.Titanium White
). Entonces, dado que probablemente necesitará un mecanismo adecuado para generar nombres de enumeración para mostrar al usuario, es mejor evitar complicar innecesariamente su enumeración.Dicho esto, por supuesto, puede seguir adelante y hacer lo que ha estado pensando en hacer, y luego refactorizar su enumeración más tarde, para pasar nombres al constructor, cuando (y si) se encuentra con problemas.
Puede eliminar un par de líneas de su enum-with-constructor declarando el
name
campopublic final
y perdiendo el captador. (¿Qué es este amor que los programadores de Java tienen hacia los getters?)fuente
public final static int white = 1;
opublic final static String white = "white";
(aparte de romper la convención nuevamente), esto pierde el tipo de seguridad que proporciona la enumeración.public final
campo de instancia que se inicializa desde el constructor se comporta exactamente como un campo no final, excepto que no se le puede asignar en tiempo de compilación . Puede modificarlo mediante reflexión y todo el código que se refiere a él comenzará a ver el nuevo valor de inmediato.Podría decirse que seguir la convención de nombres MAYÚSCULAS viola DRY . (Y YAGNI ). por ejemplo, en su ejemplo de código # 2: "ROJO" y "rojo" se repiten.
Entonces, ¿sigues la convención oficial o sigues a DRY? Tu llamada.
En mi código, seguiré DRY. Sin embargo, pondré un comentario sobre la clase Enum, diciendo "no todo en mayúsculas porque (explicación aquí)"
fuente