"The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at or repair." -Douglas Adams
我有一个类 FileItems。 FileItems 构造函数接受一个文件,如果该文件不存在,则引发异常 (FileNotFoundException)。该类的其他方法也涉及文件操作,因此能够抛出 FileNotFoundException。我想找到一个更好的解决方案。不需要其他程序员处理所有这些极不可能的 FileNotFoundExceptions 的解决方案。
事情的真相:
- 已检查文件是否存在,但极不可能的可能性是,由于现实的某些重大故障,文件可能在调用此方法之前被删除。
- 由于 1 发生的概率极不相同且不可恢复,因此我更愿意定义一个未经检查的异常。
- 该文件已经被发现存在,强制其他程序员编写代码并捕获检查的 FileNotFoundException 似乎乏味无用。该程序应该在那时完全失败。例如,计算机总是有可能catch fire, but no one is insane enough to force other programmers to handle that as a checked exception .
- 我不时遇到这种异常问题,每次遇到此问题(我的旧解决方案)时定义自定义未检查异常很烦人,并且会增加代码膨胀。
目前的代码是这样的
public Iterator getFileItemsIterator() {
try{
Scanner sc = new Scanner(this.fileWhichIsKnowToExist);
return new specialFileItemsIterator(sc);
} catch (FileNotFoundException e){ //can never happen}
return null;
}
如何在不定义自定义未检查 FileNotFoundException 的情况下做得更好?有什么方法可以将checkedException 转换为uncheckException?
最佳答案
处理这个问题的常用模式是exception chaining .您只需将 FileNotFoundException 包装在 RuntimeException 中:
catch(FileNotFoundException e) {
throw new RuntimeException(e);
}
这种模式不仅适用于在特定情况下不能发生异常的情况(例如您的情况),而且还适用于您没有办法或意图真正处理异常的情况(例如数据库链接失败)。
编辑:当心这种看起来很相似的反模式,我在野外经常看到它:
catch(FileNotFoundException e) {
throw new RuntimeException(e.getMessage());
}
这样做会丢弃原始堆栈跟踪中的所有重要信息,这通常会使问题难以追踪。
另一个编辑:正如 Thorbjørn Ravn Andersen 在他的回复中正确指出的那样,说明你为什么在评论中链接异常并没有什么坏处,或者更好的是,作为异常信息:
catch(FileNotFoundException e) {
throw new RuntimeException(
"This should never happen, I know this file exists", e);
}
关于java - 如何以安全且可读的方式处理我知道永远不会抛出的 IOException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1045829/