在 java 中使用 Null 与 ObjectNotFoundException

Using Null vs ObjectNotFoundException in java

我已经在 java 中编码了几年,我真的很喜欢尽可能不使用 null 的想法,这在大多数情况下并不太难,但我一直回来对于同一实例,我无法决定是使用 ObjectNotFoundException 还是 return null 更好。任何人对这里的最佳实践有任何想法吗?

假设您在数据库中存储了一些电子邮件订阅,您可以通过唯一密钥(代码)访问该数据库:

public EmailSubscriptionModel getSubscriptionByCode(final String code){
   //go get a list of email subscriptions from DB matching code

   if({list is not empty}){
        return list.get(0);
   }else{
        return null;
   }
}

public void subscribe(final String code){
   EmailSubscriptionModel subscription = getSubscriptionByCode(code);

   if(subscription != null){
      //do subscription
   }

 }

我能想到的避免此空检查的唯一方法是在 getSubscriptionByCode() 方法中抛出一个 ObjectNotFoundException,在这种情况下我们必须使用 try/catch像这样捕获错误:

public EmailSubscriptionModel getSubscriptionByCode(final String code) 
   throws ObjectNotFoundException{

      //go get a list of email subscriptions from DB matching code

       if({list is empty}){
          throw new ObjectNotFoundException();
       }

       return list.get(0);
}

public void subscribe(final String code){

   try{
       EmailSubscriptionModel subscription = getSubscriptionByCode(code);
       //do subscription

   }catch(ObjectNotFoundException e){
      //just move on
   }

 }

这比前者更可取吗?还是只是一种风格选择?

在预期的(= 很可能)情况下抛出异常是不好的风格。对于 API 用户来说,扔掉一个已检查的特别不愉快。

如果您真的不想避免 null 并坚持要求客户端必须考虑 null 情况,请使用 Optional<EmailSubscriptionModel> (Java 8+).

就我个人而言,我认为在实际上没有错误的情况下抛出异常是一种糟糕的模式。它只会导致不必要的开销,如果您期望其他异常,则不清楚哪些是真正的错误,哪些是正常情况。

此外,null 是有原因的。不惜一切代价避免它并抛出异常只是为了随后捕获它们并继续正常处理是不好的。

如果确实是列表为空的错误场景,那么抛出异常也可以。

returning Null 的问题在于它不是有效对象并强制调用者检查 null。异常背后的整个想法是允许您编写实现 "main logic" 的代码,而不会受到大量错误检查的阻碍。

我倾向于 return 新建对象或抛出异常。显然,这种方法假定您确实期望您应该 return 查找一个项目,但没有找到一个是错误的。

很多图书馆似乎都在遵循这种方法。显然,您希望为用户提供一种方法来检查该项目是否存在,如果不存在则抛出异常,但如果假设您应该取回某些东西但实际上没有,则抛出异常是更好的解决方案。

偶尔创建一个新项目并 return 也可以。我在为哈希图/字典实现 [] 运算符时看到过它。

假设我正在实施某种容器。我会

boolean isItemAvailable(T someParam);
T getItem(S someParam);

记录的期望是调用者将其用作:

if (isItemAvailable(myParam))
{   
   getItem(someParam);
}

首先,异常是针对异常的——如果没有找到订阅者之类的东西,你不应该抛出异常。没什么大不了的。考虑某人想要检查他们是否订阅的用例 - 如果答案是否定的(即未找到他们的订阅)它也不例外。

用异常告诉调用者遇到了无法处理的情况,处理的问题委托给调用者。

对于 java 7.

返回 null 没问题

使用 Optional java 8+ 更清洁 API。