Java 8 Необязательно. Почему из Nullable?

У меня есть вопрос, касающийся Java 8 Optional, целью которого является устранение исключений NullPointerException.

Вопрос в том, почему оба типа позволяют нам выбирать:

Optional.of(T value)     <-----non-null value, null value will throw NPE
Optional.ofNullable(T value)   <----- nullable value

Потому что я ожидаю, когда я использую:

Optional.of(nullValue);

Не будет выбрасывать NullPointerException.


Расширил мой вопрос после некоторых ответов:

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

Ответ 1

Javadoc Optional.of читает это явно:

@throws NullPointerException if value is null

и именно здесь возникает требование обработки ожидаемых вами случаев с использованием Optional.ofNullable который представляет собой небольшой блок кода в виде:

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value); // 'Optional.of'
}

Тем не менее, решение о выборе одного из других будет по-прежнему зависеть от дизайна приложения, как если бы ваша value могла быть null или нет.


С вашей стороны, это было не то, для чего на самом деле был предназначен Optional. Замечание по API разъясняет это далее (форматирование мое):

Optional в первую очередь, предназначен для использования в качестве типа возврата метода, когда существует явная необходимость представлять "нет результата", и где использование null может вызвать ошибку. Переменная, тип которой является Optional сама по себе не должна быть null; он всегда должен указывать на Optional экземпляр.


целью Optional является решение исключения NullPointerException.

За исключением: просто, чтобы ясно сказать, что выбор, конечно, неявно позволит вам определить, должен ли NPE быть запущен во время выполнения или нет. Это не определено во время компиляции все же.

Ответ 2

целью Optional является устранение исключения NullPointerException

Да, но во время использования не при создании.

Поэтому, когда вы получаете Optional от метода, вы можете избежать NPE, используя методы Optional.ifPresent, Optional.orElse, Optional.orElseGet и Optional.orElseThrow.

Но это не тот случай, когда вы создаете Optional. Поскольку это ваш собственный метод, вы должны знать, является ли объект обнуляемым или нет.


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

Стюарт Маркс

Пожалуйста, прочитайте этот пост для более подробного объяснения.

Ответ 3

Я думаю, что это довольно просто и понятно с Javadoc:

Optional.of(T value) используется, когда вы уверены, что никогда не бывает null значения, и если возникает нулевое значение, чем программа выдает исключение NullPointerException и считает это ошибкой.

Optional.ofNullable(T value) используется, когда вы знаете, что может быть null значение, и в этом случае ваша программа должна вести себя нормально.


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

Ответ 4

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

Основная задача класса Optional<T> - предоставить средство для выполнения операций отображения с нулевым безопасным отображением.

employeeOptional.map(Employee::getName).map(String::toUpperCase).ifPresent(upperCasedNameConsumer)

Выражение выше может заменить каскад операторов if-else в одном читаемом выражении.

Optional.of обеспечивает утверждение, что данный аргумент является null-null значением, в противном случае вы можете выбрать Optional.ofNullable если вы не уверены в вводе.

Я настоятельно рекомендую вам прочитать javadoc для Optional<T> класса Optional<T> чтобы получить дополнительные методы цепочки, которые вы можете использовать в своих интересах.

Ответ 5

Прочитав некоторые ответы и комментарии, я думаю, что это объяснение отсутствует. Рассмотрим метод, подобный

public Optional<String> name(Customer c) {
    return c.isNew() ? Optional.ofNullable(getName(c)) : Optional.of(getName(c));
}

Здесь вы хотите создать NullPointerException если клиент не новичок и должен иметь имя; ваш код несовместим, если это когда-либо null. Тем не менее, имя может еще не существовать, если клиент является новым, следовательно, в этом случае ofNullable и метод возвращает значение Optional.

Ответ 6

  • Optional.ofNullable - это оболочка вокруг существующих API, которая может возвращать null. Вы бы назвали это потребителем API.
  • Optional.of/Optional.empty для нового кода, написанного с учетом Optional. Вы бы вернули Optional созданный с of/empty в качестве поставщика API.