最佳实践:使用 Java 8 可选或抛出异常
Best Practice: Using Java 8 Optional or throwing Exception
Java 8 引入了 Optional
API 来表示在运行时可能是 null
的值。在以下情况下,最好是抛出检查异常还是 return Optional
return 类型来表示边缘情况?
案例 1:返回类型 Optional
private Optional<Item> getItem(String itemName)
{
for (Item item : items)
{
if (item.getName().equals(itemName))
return Optional.of(item);
}
return Optional.empty();
}
案例 2:抛出检查异常
private Item getItem(String itemName) throws ItemNotFound
{
for (Item item : items)
{
if (item.getName().equals(itemName))
return item;
}
throw new ItemNotFound();
}
正如 Martin Fowler 所提倡的那样,Optional
/特例模式是一种更好的做法,但在这个简单的场景中,抛出检查异常也能起到作用。
我应该关注哪一个?
这基本上可以归结为:这个项目丢失的用例有意义吗?
假设某个应用有用户。用户可以在他的帐户信息中添加一个 phone 号码。由于他的俯卧数不必在那里,您可以使用可选的。 Phone 号码可能存在但可能丢失。客户端代码必须处理 Optional/nullable 值。
另一方面,如果我想查看他的电子邮件,这在注册期间是强制性的。那么例外就是要走的路。电子邮件必须在那里,但没有。这里客户端代码面临无效的应用state/corrupted user.
很简单:
- 如果 null 是错误条件,则抛出异常。
- 如果 null 是一个有效的 return 值,那么 return 一个空的 Optional。
Java 8 引入了 Optional
API 来表示在运行时可能是 null
的值。在以下情况下,最好是抛出检查异常还是 return Optional
return 类型来表示边缘情况?
案例 1:返回类型 Optional
private Optional<Item> getItem(String itemName)
{
for (Item item : items)
{
if (item.getName().equals(itemName))
return Optional.of(item);
}
return Optional.empty();
}
案例 2:抛出检查异常
private Item getItem(String itemName) throws ItemNotFound
{
for (Item item : items)
{
if (item.getName().equals(itemName))
return item;
}
throw new ItemNotFound();
}
正如 Martin Fowler 所提倡的那样,Optional
/特例模式是一种更好的做法,但在这个简单的场景中,抛出检查异常也能起到作用。
我应该关注哪一个?
这基本上可以归结为:这个项目丢失的用例有意义吗?
假设某个应用有用户。用户可以在他的帐户信息中添加一个 phone 号码。由于他的俯卧数不必在那里,您可以使用可选的。 Phone 号码可能存在但可能丢失。客户端代码必须处理 Optional/nullable 值。
另一方面,如果我想查看他的电子邮件,这在注册期间是强制性的。那么例外就是要走的路。电子邮件必须在那里,但没有。这里客户端代码面临无效的应用state/corrupted user.
很简单:
- 如果 null 是错误条件,则抛出异常。
- 如果 null 是一个有效的 return 值,那么 return 一个空的 Optional。