how - ¿Por qué no hay constructor público para Opcional en java?
javadoc code documentation (4)
De Joshua Bloch para Java efectivo, Capítulo 2. Creación y destrucción de objetos, 1 artículo:
Considere métodos de fábrica estáticos en lugar de constructores
¿Por qué?
Una ventaja de los métodos estáticos de fábrica es que, a diferencia de los constructores, tienen nombres.
Con los métodos de fábrica estáticos podemos especificar algunos comportamientos de instanciación en la definición del método. Esto hace que la API sea más fácil de usar y evitamos que los clientes llamen a los constructores incorrectos.
Por ejemplo, aquí: En Optional.ofNullable
-> permitimos que se pase un valor nulo para crear una instancia del Optional , en Optional.of
valor nulo no está permitido y lanzamos una excepción. No podríamos usar el constructor aquí.
private Optional(T value) {
this.value = Objects.requireNonNull(value); //this throws NullPointerException
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
Otra ventaja (ya mencionada):
Una segunda ventaja de los métodos estáticos de fábrica es que, a diferencia de los constructores, no se requiere que creen un nuevo objeto cada vez que se invocan.
En Opcional, el valor vacío se crea una instancia solo una vez, y luego se almacena en el campo estático, este valor se reutiliza siempre cuando el programa necesita un valor vacío.
private static final Optional<?> EMPTY = new Optional<>(); //instantiate value when program starts
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY; //return stored value when requested
return t;
}
¿Por qué Optional
tiene métodos como of()
y ofNullable()
lugar de un constructor público?
Debido a que los métodos de fábrica deben ser favorecidos sobre los constructores públicos cuando se conocen los posibles casos de instanciación.
Hace que la API sea más fácil de usar para las clases de clientes.
Además, los métodos de fábrica permiten decidir si se debe crear una instancia en cada invocación.
En el caso de Optional.empty()
tiene sentido almacenar el valor en caché, ya que es inmutable.
La razón es en realidad bastante simple: un opcional vacío es una constante estática para que sea más eficiente con la memoria. Si se usara un constructor, tendría que crear una nueva instancia cada vez para un caso común.
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
Opcional es una clase basada en valor sin ningún constructor.
no tienen constructores accesibles, sino que se crean instancias a través de métodos de fábrica que no comprometen la identidad de las instancias devueltas