清单 2. RuntimeException
捕获 bug
——
模式
不要执行此模式
1 public void addInstance(String className) {
2 try {
3 Class clazz = Class.forName(className);
4 objectSet.add(clazz.newInstance());
5 }
6 catch (Exception e) {
7 logger.log("Exception in newInstance", e);
8 }
9 }
10
bug 模 式 通 常 源 自 语 言 的 模 糊 功 能 或 类 库 ;
出 现 此 bug 模 式 是 因 为
RuntimeException
扩展了 Exception
,这稍微有点违反常理。对 RuntimeException 捕获的修
——
复非常容易
您需要了解以下问题:首先捕获 RuntimeException
,并在捕获 Exception
之前重新将其抛出,如清单 3
所示。不过,即使知道 bug 模式及其修复方法,在代码审查
过程中也很容易忘记执行它或忽略它,并且编译器也不会通知您。这是引入 bug 模式的原
“
”
因,帮助您避免违犯 您已较好地了解 之类的错误。
清单 3.
通过显式处理 RuntimeException
修复 RuntimeException 捕获
1 public void addInstance(String className) {
2 try {
3 Class clazz = Class.forName(className);
4 objectSet.add(clazz.newInstance());
5 }
6 catch (Exception e) {
7 logger.log("Exception in newInstance", e);
8 }
9 }
10
编写 bug
模式的第一个步骤是清楚地标识 bug 模式。在这里,bug 模式是捕获
Exception
的 catch
块,这时不存在用于 RuntimeException 的相应捕获块,并且尝试块中
的任何方法调用或 throw
语句都不会抛出 Exception
。要检测此 bug
模式,则需要知道 try-
catch 块的位置、try
块可能抛出的内容以及在 catch 块中将捕获的内容。
标识捕获的异常
像上个月的操作一样,您可以通过创建 BytecodeScanningDetector 基础类(可实现
Visitor 模式)
的子类启动 bug
检测器。在 BytecodeScanningDetector
中有一个 visit(Code) 方
法 , 并 且 在 每 次 发 现 catch
块 时 , 该 实 现 都 会 调 用 visit(CodeException) 。 如 果 重 写
visit(Code)
,并从那里调用 super.visit(Code)
,则当超类 visit(Code) 返回时,它将调用用于