Почему нет публичного конструктора для опции в java? - программирование
Подтвердить что ты не робот

Почему нет публичного конструктора для опции в java?

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

4b9b3361

Ответ 1

От Джошуа Блоха, эффективной Java, Глава 2. Создание и уничтожение объектов, 1 предмет:

Рассмотрим статические фабричные методы вместо конструкторов

Зачем?

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

Со статическими фабричными методами мы можем указать некоторое поведение экземпляра в определении метода. Это упрощает использование API, и мы не разрешаем клиентам вызывать неправильные конструкторы.

Например, здесь: в Optional.ofNullable → мы разрешаем передать нулевое значение для создания экземпляра Optional, в 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);
} 

Еще одно преимущество (уже упоминалось):

Второе преимущество статических фабричных методов заключается в том, что, в отличие от конструкторов, они не обязаны создавать новый объект при каждом их вызове.

В Optional, пустое значение создается только один раз, а затем сохраняется в статическом поле, это значение используется повторно всегда, когда программе требуется пустое значение.

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;
}

Ответ 2

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

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);
}

Ответ 3

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

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

Ответ 4

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