我已经在java编写了几年了,我真的很喜欢在可能的情况下不使用null的想法,这在很大程度上并不太难,但我一直回到同一个实例无法决定是否更好地使用ObjectNotFoundException或只返回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
}
}
我能想到避免这种空检查的唯一方法是在ObjectNotFoundException
方法中抛出getSubscriptionByCode()
,在这种情况下我们必须使用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
}
}
这有什么理由比前者更好吗?或者它只是一种风格选择?
答案 0 :(得分:3)
在预期(=非常可能)的情况下抛出异常是糟糕的风格。抛出一个已检查的对API用户来说尤其不愉快。
如果你真的不想避免null并坚持客户端必须考虑使用Optional<EmailSubscriptionModel>
(Java 8 +)的空案例。
答案 1 :(得分:1)
返回Null的问题是它不是有效对象并强制调用者检查null。异常背后的整个想法是允许您编写实现&#34;主逻辑&#34;的代码,而不会受到大量错误检查的阻碍。
我倾向于返回新构造的对象或抛出异常。显然,这种方法假设您确实希望您应该返回一个项目,而不是找到一个是错误。
许多图书馆似乎都在遵循这种方法。显然,您希望为用户提供一种方法来检查项是否存在而不抛出异常(如果不存在),但如果假设您应该返回某些内容但不是,则抛出异常是更好的解决方案。
偶尔创建一个新项目并返回它也可以。我在为hashmaps / dictionaries实现[]运算符时已经看过了。
所以,让我们说我正在实施某种容器。我会
boolean isItemAvailable(T someParam);
T getItem(S someParam);
记录在案的期望是调用者将其用作:
if (isItemAvailable(myParam))
{
getItem(someParam);
}
答案 2 :(得分:1)
首先,异常是例外 - 如果找不到订户之类的东西,你不应该抛出异常。这没什么大不了的。考虑一个想要检查他们是否订阅的用例 - 如果答案是否定的(即他们没有找到他们的订阅)则不是例外。
使用例外来告诉调用者遇到无法处理的情况,并将处理它的问题委托给调用者。
对于java 7,返回null是正常的。
将Optional
用于java 8+以获得更清晰的API。
答案 3 :(得分:0)
就个人而言,我认为在实际上没有错误的情况下抛出异常是一种糟糕的模式。它只会造成不必要的开销,如果你期望其他例外情况,则不清楚哪些是真正的错误,哪些是正常情况。
此外,null是有原因的。不惜一切代价避免它,抛出异常只是为了抓住它们然后进行正常处理并不好。
如果列表为空的错误方案确实是错误的,那么抛出异常就可以了。