您是否同意Java类的设计者java.io.IOException应该使它成为从派生的未经检查的运行时异常,java.lang.RuntimeException而不是仅从派生的未检查的运行时异常java.lang.Exception?
java.io.IOException
java.lang.RuntimeException
java.lang.Exception
我认为该类IOException应该是未经检查的异常,因为应用程序几乎无法解决文件系统错误之类的问题。但是,在《无法抛出异常》中,Elliotte Rusty Harold声称大多数I / O错误都是暂时的,因此您可以在放弃之前多次重试一次I / O操作:
IOException
例如,一个IOComparator可能不会遇到I / O错误,但是由于许多I / O问题是暂时的,因此您可以重试几次,如清单7所示:
通常是这样吗?Java应用程序可以纠正I / O错误或等待系统恢复吗?如果是这样,则检查IOException是合理的,但是如果不是,则应取消IOException,以便业务逻辑可以将此异常的处理委托给单独的系统错误处理程序。
我完全不同意。对我来说,模型是正确的。RuntimeException是最通常表示编程逻辑中的严重错误(例如ArrayIndexOutOfBounds,NullPointer或IllegalArgument)或运行时确实确定不应发生的错误(例如SecurityException)。
相反,IOException及其派生类是在程序正常执行期间可能合理地发生的异常,并且通用逻辑将指示应解决这些问题,或者至少程序员应意识到它们可能会发生。例如,对于“文件”,如果您的应用程序记录器无法写入其数据,则您宁愿被迫捕获潜在的IOException并进行恢复,还是选择对应用程序不重要的操作来关闭整个JVM,因为没有人想到捕获该JVM。未经检查的异常(您可能已经猜到了,我将选择前者)。
我认为,在许多情况下,IOException是可恢复的,或者至少程序员应明确意识到潜在的危险,这样,如果无法恢复,则系统可能会更加“崩溃”。
就您所能想到的,如果系统无法恢复,则总是存在带有已检查异常的替代方案。您总是可以让自己的方法在抛出它们时声明它,抛出它们自己的运行时异常,或者猛烈地使JVM崩溃:
public void doit() throws IOException { try{ }catch(IOException e){ // try to recover ... // can't recover throw e; } } public void doit() { try{ }catch(IOException e){ // try to recover ... // can't recover throw new RuntimeException(e); } } public void doit() { try{ }catch(IOException e){ // try to recover ... // OH NO!!!! System.exit(Constant.UNRECOVERABLE_IO_ERROR); } }