Eth*_*man 20 java exception-handling exception ioexception
"可能出错的事情与不可能出错的事情之间的主要区别在于,当一件不可能出错的事情出错时,通常会发现无法进入或修复." -道格拉斯·亚当斯
我有一个类FileItems.FileItems构造函数接受一个文件,如果该文件不存在则抛出异常(FileNotFoundException).该类的其他方法也涉及文件操作,因此具有抛出FileNotFoundException的能力.我想找到一个更好的解决方案.一种解决方案,不需要其他程序员处理所有这些极不可能的FileNotFoundExceptions.
事情的事实:
代码目前看起来像这样
public Iterator getFileItemsIterator() {
try{
Scanner sc = new Scanner(this.fileWhichIsKnowToExist);
return new specialFileItemsIterator(sc);
} catch (FileNotFoundException e){ //can never happen}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如何在不定义自定义未经检查的FileNotFoundException的情况下更好地完成此操作?有没有办法将checkedException转换为uncheckException?
Hen*_*ing 51
解决这个问题的通常模式是异常链接.您只需在RuntimeException中包装FileNotFoundException:
catch(FileNotFoundException e) {
throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)
此模式不仅适用于在特定情况下(例如您的)不能发生异常,而且当您无法或无意真正处理异常(例如数据库链接失败)时.
编辑:要注意这种看似相似的反模式,我经常在野外看到它:
catch(FileNotFoundException e) {
throw new RuntimeException(e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
通过这样做,您可以丢弃原始堆栈跟踪中的所有重要信息,这通常会使问题难以追踪.
另一个编辑:正如ThorbjørnRavnAndersen在他的回答中正确指出的那样,无论是在评论中,还是在更好的情况下,作为异常消息,都可以说明为什么要链接异常.
catch(FileNotFoundException e) {
throw new RuntimeException(
"This should never happen, I know this file exists", e);
}
Run Code Online (Sandbox Code Playgroud)
Emi*_*l H 11
您可以通过将其嵌入RuntimException中将已检查的异常转换为未选中的异常.如果异常在堆栈中被捕获并使用printStackTrace()输出,则也会显示原始异常的堆栈.
try {
// code...
}
catch (IOException e) {
throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)
这是一个很好的解决方案,您应该毫不犹豫地在这些情况下使用.
Tho*_*sen 10
考虑使用表单
throw new RuntimeException("This should never happen", e);
Run Code Online (Sandbox Code Playgroud)
代替.这允许您向维护者传达意义,以便在阅读代码时跟随您,但也应该在某些奇怪的情况下抛出异常.
编辑:这也是通过不期望这些异常的机制传递异常的好方法.例如,如果你有一个"从数据库获取更多行"迭代器,Iterator接口不允许抛出例如FileNotFoundException,所以你可以像这样包装它.在使用迭代器的代码中,您可以捕获runtimeexception并使用getCause()检查原始的excpetion.在浏览遗留代码路径时非常有用.
如果您的位置不太可能并且应该只是结束程序,请使用现有的运行时异常,甚至RuntimeException本身(如果不是IllegalStateException).
try {
....
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
19753 次 |
最近记录: |