От эффективной работы Java Джошуа Блоха, Глава 2. Создание и уничтожение объектов, 1 Item:
Рассмотрим статические фабричные методы вместо конструкторов
Почему?
Одним из преимуществ статических фабричных методов является то, что, в отличие от конструкторов, они имеют имена.
С помощью статических фабричных методов мы можем указать некоторые особенности реализации в определении метода.Это упрощает использование API, и мы не разрешаем клиентам вызывать неправильные конструкторы.
Например, здесь: в Optional.ofNullable
-> мы разрешаем передавать нулевое значение для создания экземпляра Необязательно , в Optional.of
нулевое значение не допускается и выдается исключение.Мы не могли использовать конструктор здесь.
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);
}
Другое преимущество (уже упомянутое):
Второе преимущество статических фабричных методов заключается в том, что, в отличие от конструкторов, они не требуютсядля создания нового объекта каждый раз, когда они вызываются.
В Необязательном, пустое значение создается только один раз, а затем сохраняется в статическом поле, это значение используется повторно всегда, когда программе требуетсяпустое значение
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;
}