最佳实践:使用Java 8的Optional或抛出异常

4

Java 8引入了Optional API,用于表示在运行时可能为null的值。在以下情况下,是最好抛出已检查异常还是返回Optional返回类型以表示边缘情况?

情况1:返回类型Optional

private Optional<Item> getItem(String itemName)
{
    for (Item item : items)
    {
        if (item.getName().equals(itemName))
            return Optional.of(item);
    }

    return Optional.empty();
}

情况二:抛出已检查的异常

  private Item getItem(String itemName) throws ItemNotFound
   {
        for (Item item : items)
        {
            if (item.getName().equals(itemName))
                return item;
        }

        throw new ItemNotFound();
   }

正如Martin Fowler所提倡的那样,Optional/Special case模式是更好的实践方法,但在这种简单的情况下,抛出已检查异常也可以完成工作。

我应该遵循哪个?


1
这些“null”安全类型都是很大的开销,因此不要使用它们,直接返回“null”,并记录该方法的结果可能为“null”。我认为使用if(resultOptional.isPresent())if(result == null)相比没有太大优势,但这只是我的个人意见。同样地,我认为只有在极端情况下才应该抛出异常。 - Lino
@AxelH 抱歉,我修复了我的代码示例。应该是 throw new ItemNotFound() - Vino
异常应该用于特殊情况,那么它是一个预期的特性还是不是?如果是的话,那么你不需要一个异常,可以返回null或者Optional。没有所谓的“好方法”。 - AxelH
请解释一下为什么要给我点踩。 - Vino
2
@Lino 可选项存在的目的是为了在代码中表达可空性,而不是文档。它的存在是为了我们不必记住记录可空性。此外,在确定可选项是性能瓶颈之后再谈论开销。此时只是过早的优化。 - Torben
2个回答

7
这基本上可以归结为:在这种情况下,缺少项目是否有意义?
假设一个应用程序有用户。用户可以向其帐户信息中添加电话号码。由于他的电话号码不一定存在,因此可以使用可选项。电话号码可能存在,但也可能不存在。客户端代码必须处理可选/可空值。
另一方面,如果我想查看他的电子邮件地址,在注册期间是必填的。那么异常就是正确的方式。电子邮件必须存在,但实际上不存在。在这种情况下,客户端代码面临无效的应用程序状态/损坏的用户。

谢谢。这是最有意义的。 - Vino

3

这很简单:

  • 如果null是一个错误状态,那么抛出异常。
  • 如果null是一个有效的返回值,那么返回一个空的Optional。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接