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?


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.


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.


1
¿Por qué escogieron AssertionErrorsobre otras alternativas como IllegalStateException, UnsupportedOperationException, etc.?
Pacerier

@Pacerier Mira esto .
bcsb1001

@ bcsb1001, eso nos lleva a esto .
Pacerier

21

Parece que tiene una clase de utilidad similar a java.lang.Math .
El enfoque allí es la clase final con constructor privado y métodos estáticos.

Pero tenga cuidado con lo que esto hace para la comprobabilidad, le recomiendo leer este artículo
Los métodos estáticos son la muerte de la testabilidad


Entonces, ¿es java.lang.Math "muerte a prueba"?
Pacerier

1
Podría ser interesante ver cómo se apunta cuando se ejecuta a través code.google.com/p/testability-explorer
Crowne

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


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.


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

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).


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.