with values recorrer programacion enum clase java enums private-constructor

recorrer - java enum with values



Diferencia entre java enum sin valores y clase de utilidad con constructor privado (4)

Una cosa común que hacer a las clases de utilidad es darles un constructor privado :

public final class UtilClass { private UtilClass() {} ... }

Pero desafortunadamente, algunas herramientas no les gusta ese constructor privado. Pueden advertir que nunca se llama dentro de la clase, que no está cubierto por pruebas, que el bloque no contiene un comentario, etc.

Muchas de esas advertencias desaparecen si haces esto en su lugar:

public enum UtilClass {; ... }

Mi pregunta es: además del odio interminable de los futuros desarrolladores, ¿qué diferencias importantes existen entre una enumeración sin valores y una clase con un constructor privado en Java?

Tenga en cuenta que no estoy preguntando ¿Cuál es la ventaja de una enumeración Java frente a una clase con campos finales públicos estáticos? . No estoy decidiendo si una lista de cosas debe ser un conjunto de constantes o una enumeración, estoy decidiendo entre poner un conjunto de funciones en una clase sin constructor o una enumeración sin valor.

También tenga en cuenta que en realidad no quiero hacer esto. Solo quiero saber las ventajas y desventajas como parte del conocimiento general del idioma.

Por ejemplo, el uso de una enumeración contamina la autocompletar con métodos inútiles como UtilClass.values() . ¿Qué otras desventajas hay? Upsides?


El siguiente patrón en las clases de utilidad también proporciona una garantía irrompible de que no puede haber instancias:

public abstract class Util { private Util() { throw new Error(); } ... // static methods }

Además, no tienes métodos estáticos adicionales irrelevantes, proporcionados por enums.


La única diferencia es que todavía puedes llamar al constructor dentro de tu clase :

public final class UtilityClass { public static final UtilityClass Instance = new UtilityClass(); private UtilityClass () {} public static int Foo (int a, int b) { return a+b; } }

Pero dado que usted es el diseñador de esa clase, no tendría sentido romper sus propios contratos de código.

En general, la mayoría de los libros de diseño de software que he leído están en contra de usar métodos estáticos . A menos que sean realmente métodos de utilidad: en el sentido de que nunca requerirán ningún estado. Y aun así, implementar un patrón de Singleton es tan solo un pequeño esfuerzo que, cuando llegue el momento, puede asignarle un estado:

public final class UtilityClass { public static final UtilityClass Instance = new UtilityClass(); private UtilityClass () {} public int Foo (int a, int b) { return a+b; } }

Y llamándolo con UtilityClass.Instance.Foo(2,5); . Sería mucho más difícil realizar una transformación de estado de introducción más adelante en el proceso de codificación. Por lo tanto, los métodos estáticos son más difíciles de mantener.

La razón por la cual las instancias son útiles es que puedes usarlas en muchos patrones como Estrategia si en una ocasión depende de algo que deba hacerse, ... Al usar métodos static , uno hace que los métodos sean menos dinámicos porque Java no lo hace t indicadores de método de soporte (por buenas razones). Por lo tanto, los métodos no estáticos son más dinámicos y útiles.

Además, algunos investigadores de seguridad argumentan que es más difícil analizar código con modificadores static ya que se puede acceder desde cualquier lugar y los efectos secundarios son menos predecibles (por ejemplo, en una herramienta de análisis de seguridad automática): supongamos que tiene una clase que no está completamente implementada , entonces aún puede analizar los campos para saber a qué métodos puede acceder y así analizar los posibles efectos secundarios (uso de la red, archivo IO, ...). Esto puede generar una lista de posibles peligros por clase que se debe verificar. Al menos si entendí correctamente la disertación de doctorado de uno de mis colegas investigadores. Por lo tanto, los métodos no estáticos permiten un mayor análisis de modificador.

Para concluir: Java se construyó sobre el principio de la programación orientada a objetos. Esto significa que el "mundo de las clases" es utilizado por el editor y el "mundo de instancias" por el intérprete / tiempo de ejecución. Estoy de acuerdo que hay muchos conflictos entre las dos palabras. Pero en muchos / algunos casos, static métodos static son un error para resolver dichos conflictos.


Un beneficio es que está absolutamente garantizado de que no se pueden crear instancias, incluso desde el interior de la clase.

Una desventaja es que esto va más allá de la intención habitual de las enumeraciones. Sin embargo, ya hacemos esto para singletons implementados con enums.

Este fragmento de "Effective Java" de Joshua Bloch sobre tales singletons también se aplica a las clases de utilidad:

... obtienes una garantía férrea de que no puede haber instancias además de las constantes declaradas. La JVM hace esta garantía y puede confiar en ella.

Descargo de responsabilidad: no he usado este patrón, y no estoy recomendando a favor o en contra.


Usar enum para algo que no es realmente una enumeración es feo y confuso. Yo diría que es razón suficiente para no hacerlo.

El patrón de "clase de utilidad" es perfectamente legítimo. Si a sus herramientas no les gusta, es un problema con las herramientas.