陷阱 - 返回 null 而不是抛出异常
一些 Java 程序员普遍厌恶抛出或传播异常。这导致代码如下:
public Reader getReader(String pathname) {
try {
return new BufferedReader(FileReader(pathname));
} catch (IOException ex) {
System.out.println("Open failed: " + ex.getMessage());
return null;
}
}
那有什么问题呢?
问题是 getReader
将 null
作为一个特殊值返回,表示 Reader
无法打开。现在需要测试返回值以查看它是否在使用之前是 null
。如果省略测试,结果将是一个 NullPointerException
。
这里实际上有三个问题:
IOException
很快被捕捉了。- 此代码的结构意味着存在泄漏资源的风险。
- 使用
null
然后返回,因为没有真正的Reader
可用于返回。
事实上,假设异常确实需要像这样早点发现,有几种方法可以返回 null
:
- 可以实现
NullReader
类; 例如,API 的操作就像读者已经处于文件结束位置一样。 - 使用 Java 8,可以将
getReader
声明为返回Optional<Reader>
。