una tipos tener simple puede polimorfismo herencia ejercicios ejemplos cuantos constructores clase java coding-style throwable

java - tipos - ¿Cuál es el Throwable preferido para usar en un constructor de clase de utilidad privada?



super en java (6)

¿Qué pasa con IllegalAcessError ? :)

Effective Java (Second Edition) , Item 4, discute el uso de constructores privados para imponer la no instantabilidad. Aquí está el ejemplo del código del libro:

public final class UtilityClass { private UtilityClass() { throw new AssertionError(); } }

Sin embargo, AssertionError no parece ser lo correcto para arrojar. Nada está siendo "afirmado", que es como la API define el uso de AssertionError .

¿Hay un Throwable diferente que sea típicamente en esta situación? ¿Uno generalmente arroja una Exception general con un mensaje? ¿O es común escribir una Exception personalizada para esto?

Es bastante trivial, pero más que nada, supongo que estoy curioso sobre esto desde una perspectiva de estilo y estándares.


Hay una afirmación: "Estoy afirmando que este constructor nunca se llamará". Así que, de hecho, AssertionError es correcto aquí.


Una afirmación quebrada significa que ha roto una especificación contractual de su código. Entonces es lo correcto aquí.

Sin embargo, como supongo que creará instancias privadas de una instancia, también llamará al constructor y provocará un error, a menos que tenga otro constructor.


UnsupportedOperationException suena como la mejor opción, aunque una excepción marcada sería incluso mejor, ya que podría advertir a alguien al crear una instancia errónea de la clase en tiempo de compilación.


Me gusta incluir el comentario de Bloch:

// Suppress default constructor for noninstantiability

O mejor aún poniéndolo en el Error:

private UtilityClass() { throw new AssertionError("Suppress default constructor for noninstantiability"); }


No, no, no, con el debido respeto a Josh Bloch, nunca arrojes un AssertionError menos que sea por una afirmación. Si desea un AssertionError aquí, tírelo con assert(false) . Entonces, alguien que lea el código puede encontrarlo más tarde.

Aún mejor, defina su propia excepción, diga CantInstantiateUtilityClass . entonces tendrás un código que diga

try { // some stuff } catch (CantInstantiateUtilityClass e) { // react }

para que el lector del receptor sepa lo que sucedió.

Actualizar

De vez en cuando, algún maldito tonto vagabundea por aquí y lo vota de nuevo, casi cuatro años después del hecho. Por lo tanto, permítanme señalar que el estándar todavía define AssertionError como el resultado de una afirmación fallida, no como lo que un principiante piensa que debería ser lanzado en lugar de una excepción informativa bien definida. Tristemente, una buena disciplina de excepción es quizás la habilidad menos recomendada en la programación de Java.