Java: ¿clase estática?

130

Tengo una clase llena de funciones de utilidad. Crear instancias de una instancia no tiene sentido semántico, pero todavía quiero llamar a sus métodos. ¿Cuál es la mejor manera de lidiar con esto? Clase estática? ¿Resumen?

Nick Heiner
fuente
14
Por cierto, no puedes hacer que una clase de nivel superior esté estática ...
Jon

Respuestas:

163

Constructor privado y métodos estáticos en una clase marcada como final.

David Robles
fuente
19
@matt b: Como David Robles señala en su respuesta, no es necesario que la clase sea final ... no se puede subclasificar porque una subclase no podrá invocar a un constructor de superclases porque es privada. Sin embargo ... no hay daño en ser explícito. Pero jfyi :-).
Tom
93

Según el gran libro "Java efectivo" :

Artículo 4: imponer la no instantabilidad con un constructor privado

- Intentar imponer la no instantabilidad haciendo un resumen de clase no funciona.

- Se genera un constructor predeterminado solo si una clase no contiene constructores explícitos, por lo que una clase puede hacerse no instantable al incluir un constructor privado:

// Noninstantiable utility class
public class UtilityClass
{
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
}

Debido a que el constructor explícito es privado, es inaccesible fuera de la clase. AssertionError no es estrictamente necesario, pero proporciona un seguro en caso de que el constructor se invoque accidentalmente desde dentro de la clase. Garantiza que la clase nunca se instanciará bajo ninguna circunstancia. Este modismo es ligeramente contradictorio, ya que el constructor se proporciona expresamente para que no se pueda invocar. Por lo tanto, es aconsejable incluir un comentario, como se muestra arriba.

Como efecto secundario, este idioma también evita que la clase se subclasifique. Todos los constructores deben invocar un constructor de superclase, explícita o implícitamente, y una subclase no tendría un constructor de superclase accesible para invocar.

David Robles
fuente
1
¿Por qué escogieron AssertionErrorsobre otras alternativas como IllegalStateException, UnsupportedOperationException, etc.?
Pacerier
@Pacerier Mira esto .
bcsb1001
@ bcsb1001, eso nos lleva a esto .
Pacerier
6

Solo para nadar río arriba, los miembros estáticos y las clases no participan en OO y, por lo tanto, son malvados. No, no es malo, pero en serio, recomendaría una clase regular con un patrón singleton para acceder. De esta manera, si necesita anular el comportamiento en cualquier caso en el futuro, no es una reestructuración importante. OO es tu amigo :-)

Mi $ .02

Bennett Dill
fuente
17
Los solteros también se consideran malvados.
Dan Dyer, el
3
Utiliza el constructor privado para evitar que alguien cree instancias o subclasifique la clase. Vea la respuesta de David Robles: stackoverflow.com/questions/1844355/java-static-class/…
rob
55
singleton no es más malvado que la inyección de dependencia :)
irreputable
12
OO tiene su lugar, pero hay momentos en que simplemente no es práctico, o sería un desperdicio de recursos, por ejemplo, algo tan simple como Math.abs (). No hay ninguna razón para crear una instancia de un objeto solo por instanciar un objeto, cuando una llamada de método estático le hubiera servido igual de bien sin ninguna de las sobrecargas de OO. ;)
robar el
2
@rob re OO, estoy de acuerdo, Math.Abs ​​probablemente nunca necesite una instancia. Cuando escucho "tengo una clase de utilidad", veo Math.Avg (), donde ahora necesita agregar soporte para un promedio ponderado. Veo un generador de URL, param in, url out que necesita ser refactorizado para admitir href, o solo url, etc. Por estas razones, tener la clase de utilidad basada en OO puede pagar. Además, ahora dejaré caer la táctica defensiva OO estándar, ¡pruebas! / me ducks
Bennett Dill el
3

comentar los argumentos del "constructor privado": vamos, los desarrolladores no son tan estúpidos; pero son flojos. crear un objeto y luego llamar a métodos estáticos? No va a pasar.

no gastes demasiado tiempo para asegurarte de que tu clase no pueda ser mal utilizada. Ten un poco de fe para tus colegas. y siempre hay una manera de usar mal tu clase sin importar cómo la protejas. Lo único que no puede ser mal utilizado es algo completamente inútil.

irreputable
fuente
77
Alguien que ha visto (en el código de producción, no solo el código del estudiante) object.staticMethod ¡Creo que sobreestimas las habilidades de Joe Random Programmer! :-P
TofuBeer
2
  • Clase final y constructor privado (bueno pero no esencial)
  • Métodos públicos estáticos
fastcodejava
fuente
1

No tiene sentido declarar la clase como static. Simplemente declare sus métodos staticy llámelos desde el nombre de la clase como normal, como la clase de Matemáticas de Java .

Además, aunque no es estrictamente necesario hacer que el constructor sea privado, es una buena idea hacerlo. Marcar el constructor como privado evita que otras personas creen instancias de su clase y luego llamar a métodos estáticos desde esas instancias. (Estas llamadas funcionan exactamente igual en Java, solo son engañosas y perjudican la legibilidad de su código).

Bill el lagarto
fuente
1
Además, no olvide hacer un constructor privado.
Asaph
@Asaph: De acuerdo. Agregué un poco sobre eso a mi respuesta. Gracias.
Bill the Lizard
Si desea métodos estáticos dentro de una clase interna, la clase también debe ser estática.
Rui Marques