Notas de estudio @Effective Java
El contenido del artículo proviene del libro Joshua Bloch-Effective Java (3rd) -2018.chm
Capitulo dos
Crear y anular el registro de objetos
El elemento 4 que no se puede instanciar debe tener un constructor privado
Hacer cumplir la no instanciabilidad con un constructor privado
A veces, desea escribir una clase que contenga solo un conjunto de métodos y campos estáticos
Este tipo de críticas en la industria, en lo que respecta al objeto, porque algunas personas lo usan sin cerebro, pero tienen usos efectivos.
- Pueden agrupar métodos relacionados usando valores primitivos o matrices, usando java.lang.Math o java.util.Arrays
- También se pueden usar para agrupar métodos estáticos de objetos que implementan ciertas interfaces, usando el archivo java.util.Collections
- O bien, estas clases se pueden usar para agrupar métodos en clases finales porque no se pueden poner en subclases
- (Java8 y posterior, también puede poner estos métodos en la interfaz, si modifica estos métodos)
Tales clases de utilidad no están diseñadas para ser instanciadas: un ejemplo de este tipo no tiene sentido
Sin embargo, en ausencia de un constructor explícito, el compilador proporciona un constructor predeterminado público y sin parámetros.
Para los usuarios, este constructor no es diferente de cualquier otro constructor
No es raro ver accidentalmente clases instanciables en API publicadas
Intentar imponer no instanciables haciendo que la clase sea abstracta no funcionará
La clase puede ser una subclase y la subclase puede instanciarse
Además, induce a error a los usuarios a pensar que la clase está diseñada para heredar
Sin embargo, existe un uso simple para garantizar que no sean instancias
El constructor predeterminado solo se generará cuando la clase no tenga un constructor explícito, por lo que
Puede hacer que la clase no se pueda instanciar si incluye un constructor privado:
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
... // Remainder omitted
}
Debido a que el constructor explícito es privado, no es accesible fuera de la clase.
El error AssertionError no es estrictamente necesario, pero proporciona un método de seguro para evitar la transferencia accidental del constructor desde la clase.
Garantiza que la clase no será instanciada bajo ninguna circunstancia.
Este idioma es un poco contradictorio, porque el constructor se proporciona explícitamente y aún no se puede llamar.
Entonces, como en el ejemplo anterior, es aconsejable agregar comentarios
Como efecto secundario, este modismo también evita que las clases se subclasifiquen
(En circunstancias normales) todos los constructores deben llamar al constructor de la clase principal, ya sea explícita o implícitamente, (pero en este caso) la clase secundaria no tendrá un constructor de clase principal accesible para llamar.