Использование Optional.empty () внутри catch - PullRequest
1 голос
/ 29 марта 2019

У меня есть существующий метод, в котором я бросил RuntimeException, поймав IOException.Теперь, согласно моему требованию, я собираюсь изменить определение следующим образом:

try {
    // error/null producing code
    Optional.of(myModel);
}catch(IOException ex) {
    // here I removed throw new RuntimeException(ex);
    Optional.empty();
}

Это хорошая практика или я должен оставить существующий метод таким, какой он есть?

1 Ответ

2 голосов
/ 29 марта 2019

До Optional, если вы вызывали метод MyModel getMyModel(), вы могли получить только два значения:

  • экземпляр MyModel, означая, что все прошло нормально, и значение было найдено;или
  • null, что означает либо:
    • , что все прошло нормально, но не было значения для возврата;или
    • что-то пошло не так и метод не может вернуть значение.

Конечно, для третьего сценария вы всегда можете вызвать исключение вместовозвращая null, но иногда это не то, что вам нужно.

Optional был введен частично для лучшей дифференциации этих сценариев.Так что теперь вместо возврата MyModel вы бы объявили метод как Optional<MyModel> getMyModel(), что означало, что вы могли бы вернуть (предупреждение: плохое программирование впереди):

  • an Optional.of(myModel) экземпляр, означающий, что все прошло нормально и было найдено значение;или
  • экземпляр Optional.empty(), означающий, что все прошло нормально, но возвращаемого значения не было;или
  • null, означающее, что что-то пошло не так, и метод не может вернуть значение.

Однако основная цель Optional состояла в том, чтобы избежать NPE, вызванныхметоды, возвращающие null, вскоре было обнаружено, что , возвращающий null из метода, объявленного как возвращающий Optional, был Bad Code ™ , поэтому теперь принято возвращать Optional.empty() в тех же двух случаяхкуда вы вернулись null до.

Итак да, возвращение Optional.empty() в случае перехваченного исключения является одним из ожидаемых вариантов использования Optional.
Вы по-прежнемуне может различить «нет значения» и «ошибка», но, по крайней мере, вы заставляете вызывающего абонента учитывать возможное отсутствие значения и причину того, что он хочет сделать в этом случае: избегайте любых действий с ifPresent(),примите значение по умолчанию с orElseGet(), сгенерируйте исключение с orElseThrow и т. д.

Источник: Эффективная Java (3-е изд.), "Элемент 55: Разумное возвращение опций".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...