Clean Code – 使用Runtime Exception

By | 2019年4月14日

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来描述。

搜狗截图_2019-04-14_23-10-01