在catch中使用Optional.empty()

时间:2019-03-29 10:19:18

标签: exception java-8

我有一个现有方法,其中我通过捕获RuntimeException抛出了IOException。现在按照我的要求,我将定义更改为如下所示。

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

这是一种好习惯还是应该保持现有方法不变?

1 个答案:

答案 0 :(得分:1)

Optional之前,如果调用MyModel getMyModel()方法,则只能获得两个值:

  • 一个MyModel实例,表示一切正常,并找到了一个值;或
  • null,意思是:
    • 一切正常,但没有返回的价值;或
    • 出现问题,该方法无法返回值。

当然,对于第三种情况,您总是可以抛出异常而不是返回null,但这有时不是您想要的。

引入

Optional部分是为了更好地区分这些情况。因此,现在,不用返回MyModel,而是将方法声明为Optional<MyModel> getMyModel(),这意味着您可以返回(警告:前面的编程不好):

  • 一个Optional.of(myModel)实例,表示一切正常,并找到了一个值;或
  • Optional.empty()实例,意味着一切正常,但没有返回值;或
  • null,表示出了点问题,该方法无法返回值。

但是,由于Optional的主要目的是避免由返回null的方法引起的NPE,因此很快发现,从声明为返回的方法中返回null Optional是Bad Code™,因此现在的惯例是,在您之前返回Optional.empty()的两种情况下,都将返回null

是的,在捕获到异常的情况下返回Optional.empty()Optional的预期用途之一
您仍然无法区分“无价值”和“错误”,但是至少您必须强迫调用者考虑可能没有价值的情况,以及在这种情况下他们想要做什么的原因:避免使用{{ 1}},使用ifPresent()设置默认值,使用orElseGet()引发异常,等等。

来源:有效的Java (第3版),“项目55:明智地返回可选内容”。