2012-04-05 91 views
2

全部。我正在读一本书,在写一个方法时,其中一个想法是“不要返回null”。他建议当函数必须返回null时,“抛出异常”或“使用特殊情况”。不返回null - 返回什么搜索功能

如果方法返回类型是一个列表,我知道我可以返回一个空列表而不是null。但是,如果返回类型是特定对象呢?例如,一种通过唯一ID搜索数据库并返回结果的方法。如果方法找不到任何东西,我应该返回什么?

我试图使用“抛出异常”,但最终为任何地方写入更多的编码和附加逻辑来调用函数。

任何建议将受到赞赏。

+0

的[玩转Java的try/catch语句,并保持清洁的代码,而无需返回一个空]可能重复(http://stackoverflow.com/问题/ 9775471/get-around-javas-try-catch-and-keep-the-code-clean-without-returning-a-null) – 2012-04-05 21:56:02

+0

这本书叫什么名字? – hithwen 2013-10-14 15:53:09

+0

这是调用“干净的代码”,但我想stackoverflow不喜欢名称上显示的帖子,所以有人删除它 – 2013-10-16 05:37:21

回答

1

抛出异常是昂贵的操作,因为有上下文切换和大量的调试信息被收集,所以你要避免将它们作为控制流程流程的一种方式(特别是如果您可以处理这种情况而不会抛出异常)。返回null可以完全接受,以避免捕捉异常。

这个实例的一个例子是C#中的一对LINQ functions。这些方法可以返回空值:

SingleOrDefault(); // returns a single instance of an object, or null if not found 

FirstOrDefault(); // returns the first matching object, or null if not found 

这允许您检查null而不尝试通过异常处理找出控制流。

我能想到的一个例外(赦免双关语)是使用异常来跨越程序边界进行通信。例如,如果您的数据访问层位于单独的DLL中,并且您需要将数据库故障传递回父程序,则有时最好的方法是通过异常处理。

3

如果你不想返回null,那么你可以使用类似Optional类。

+1

可选的好处是什么。从我的角度来看,它仅将(obj == null)更改为(可选 .absent()) – 2012-04-06 16:45:38

+1

它为代码提供了一些额外的类型安全性 - null在其意图中更模糊,并且可能导致细微的错误客户端不能正确处理它。番石榴的动机是:http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained – fgb 2012-04-06 17:11:10

1

空被定义为不存在,它似乎完全符合你想要的。如果你的代码没有返回任何东西,对吧?

但是,一如既往,这取决于。

如果你的代码不是不返回任何内容,那么这样做可能会导致难以解决的问题。在这种情况下,抛出异常肯定更好。 1/null,无处不在。

如果不存在是一个完全有效的返回值,那么为什么你想要返回一个异常呢?假设你已经有了代码来处理从你的查询中返回的不存在的值,那么根本不需要抛出异常。

+0

同意。就我而言,该方法可能找不到任何东西,因此null无意义。但人们一直在谈论“方法不应该返回null”。我很难真正实现这样的想法 – 2012-04-06 16:47:47

0

我没有看到任何问题返回null,但抛出异常似乎是最明智的选择。你最好的选择是创建你自己的自定义Exception类。

代码应该差不多相同的两种方式:

try { 
    SearchResult someResult = searchForStuff(); 
} 
catch (ResultNotFoundException rnfe) { 
    /* do stuff */ 
} 


/* almost the same as this */ 

SearchResult someResult = searchForStuff(); 

if (someResult == null) { 
    /* do stuff */ 
} 
1

如果Null可能是您可能返回的可能值,那么如果找不到任何东西,则不应返回Null。例如,在:

[1, 2, 3, Null, 5].find(nonInteger) -> Null 
[1, 2, 3, 4].find(nonInteger) -> Null 

.find函数不能返回Null来表示失败,因为有时它会成功返回Null!相反,你可以改变的语义,或使用特殊的对象:

# changed semantics (with extra information returned) 
[1, 2, 3, Null, 5].find(nonInteger) -> index=4, value=Null 
[1, 2, 3, 4].find(nonInteger) -> index=Null, value=Null 

# changed semantics (with wrapper) 
[1, 2, 3, Null, 5].find(nonInteger) -> new Maybe(Null) 
[1, 2, 3, 4].find(nonInteger) -> new Maybe() 

# special object 
NoResultFound = new object() 
[1, 2, 3, Null, 5].find(nonInteger) -> Null 
[1, 2, 3, 4].find(nonInteger) -> NoResultFound