Why does Optional
have methods like of()
and ofNullable()
instead of a public constructor?
No, Constructors can be public , private , protected or default (no access modifier at all). Making something private doesn't mean nobody can access it. It just means that nobody outside the class can access it.
Java doesn't require a constructor when we create a class. However, it's important to know what happens under the hood when no constructors are explicitly defined. The compiler automatically provides a public no-argument constructor for any class without constructors. This is called the default constructor.
public final class Optional<T> extends Object. A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
A constructor is a special member function of a class which initializes objects of a class. In C++, constructor is automatically called when object of a class is created. By default, constructors are defined in public section of class.
From Joshua Bloch effective Java, Chapter 2. Creating and Destroying Objects, 1 Item:
Consider static factory methods instead of constructors
Why?
One advantage of static factory methods is that, unlike constructors, they have names.
With static factory methods we can specify some instantiation behavior in the method definition. This makes the API easier to use and we prevent clients from calling wrong constructors.
For instance here: In Optional.ofNullable
-> we allow null value be passed to instantiate the Optional, in Optional.of
null value is not allowed and throw exception. We could not use the constructor here.
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);
}
Another advantage (already mentioned):
A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.
In Optional, the empty value is instantiated just once, and then stored in the static field, this value is reused always when the program needs an empty value.
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;
}
The reason is actually quite simple: an empty optional is a static constant to be more memory efficient. If a constructor were used, it would have to create a new instance every time for a common case.
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);
}
Optional is a Value-based Class without any constructors
do not have accessible constructors, but are instead instantiated through factory methods which make no committment as to the identity of returned instances
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With