Checked Exception对于高质量软件的生产,并非是必须的。C#不支持Checked Exception; 尽管做过勇敢的尝试,C++最后也不支持Checked Exception;Python和Runby同样如此。这些编程语言都能写出高质量的软件,我们得思考是否值得使用Checked Exception。
使用Checked Exception的代价是:违反了开放、封闭原则。如果你在方法中抛出了Checked Exception,而catch语句在三个层级之上,你就得在catch语句和抛出异常处之间的每个方法签名中声明该异常。假设底层修改异常或抛出新的Checked Exception,则每个调用函数链都要修改。以此类推,最终得到一个从软件最底端贯穿到最高端的修改链,封装被打破了。
如果在编写一套代码库,Checked Exception比较有用。对于一般的开发,Runtime Exception带来的成本高于收益。
Checked Exception在方法签名上,必须添加throws 语句,定义抛出的异常。而Runtime Exception需要在方法注释中添加@exception告知其可能抛出的异常,否则调用则根本不知道方法会抛出什么Runtime Exception。
/** * Read file content. * * @param filePathStr the file path. * @return a list of file content. * @throws IOException when read file failed. * @exception IllegalArgumentException if argument filePathStr is null. */ public List<String> readFile(String filePathStr) throws IOException { if (filePathStr == null) { throw new IllegalArgumentException("File path cannot be null"); } return Files.readAllLines(Paths.get(filePathStr)); }
@exception不仅可以注释Runtime Exception,Checked Exception也可以用。不过为了区分:
- @throws注释Checked Exception。
- @exception注释Runtime Exception。
下面是InputStream的read()方法,抛出的异常都用@exception来描述。