Почему нет публичного конструктора для Optional в Java? - PullRequest
0 голосов
/ 02 декабря 2018

Почему Optional имеет методы типа of() и ofNullable() вместо открытого конструктора?

Ответы [ 4 ]

0 голосов
/ 02 декабря 2018

От эффективной работы 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;
}
0 голосов
/ 02 декабря 2018

Поскольку фабричные методы должны быть предпочтительнее общедоступных конструкторов, когда известны возможные случаи реализации.
Это облегчает использование API для клиентских классов.
Кроме того, фабричные методы позволяют решить, следует ли создавать экземпляр вкаждый вызов.
В случае Optional.empty() имеет смысл кэшировать значение, поскольку оно является неизменным.

0 голосов
/ 02 декабря 2018

Причина на самом деле довольно проста: пустой необязательный параметр является статической константой, чтобы повысить эффективность использования памяти.Если бы использовался конструктор, ему пришлось бы каждый раз создавать новый экземпляр для общего случая.

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);
}
0 голосов
/ 02 декабря 2018

Необязательным является Класс на основе значений без каких-либо конструкторов

не имеет доступных конструкторов, но вместо этого создается с помощью фабричных методов, которые не делают никаких обязательств в отношенииидентичность возвращенных экземпляров

...