处理不可能发生的异常的最佳方法

时间:2015-06-13 22:01:32

标签: java exception-handling

我使用以下代码构建一个SQL语句,用于更新特定对象所具有的字段的值。我的问题是,因为我检查对象是否具有特定字段,所以异常永远不会发生。使这段代码更具可读性的最佳方法是什么,例如避免使用try {} catch {}块。

 List<Field> modelFields = Arrays.asList(model.getClass().getFields());
 String updateString = "";

 for (Field field : fields) {
   if (modelFields.contains(field)) {
            try {
                updateString += " " + field.get((Object) model) + " ";
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            updateString += " NULL ";
        }
    }

3 个答案:

答案 0 :(得分:9)

如果您认为异常永远不会发生,那么抛出一个包装原始异常的运行时异常:

try {
    updateString += " " + field.get((Object) model) + " ";
} catch (IllegalAccessException e) {
    throw new IllegalStateException("this should never happen: the field is supposed to be public and thus accessible", e);
}

这样一来,如果你出错了,或者代码发生变得可能,那么你就会有一个例外,它有一个明确的错误信息和异常的根本原因,而不是默默地忽略错误并在以后获得无关的错误,或者更糟糕的是,这是一个有效但不正确的结果。

答案 1 :(得分:1)

我同意@JBNizet的回答。但是,在所有情况下都可能,你会想要一个不会发生的异常。

我承认这可能与OP的意图有点不同,但我认为仍然有助于在更广泛的背景下提出正确答案。

见下面的例子。

a:hover {
  /*styles*/
} 

假设某人添加了第3个枚举值public class App { enum Which {ONE, TWO}; String on(Which which) { switch (which) { case ONE: return "This is one"; case TWO: return "This is another"; default: throw new IllegalStateException("Missing case: "+which.name()+" of Which"); } } } 。这段代码总是可以正常编译,编辑器(Netbeans / Eclipse)也永远不会将此标记为问题。您只会在运行时遇到问题。

在这种情况下,我甚至建议确保没有定义明确抛出异常的THREE个案例。如果在javac或编辑器中选择了正确的设置,它至少会被更早地标记。在最坏的情况下,它会编译,但在运行时,你仍然会得到一个RuntimeException:

线程中的异常&#34; main&#34; java.lang.RuntimeException:无法编译的源代码 - 缺少return语句

有点可疑......&#39; Uncompilable&#39;在运行期间......

这仅适用于编译器或编辑器应该能够弄清楚的绑定开关集,这意味着只有Enum,而不是String或int。对于这些情况,我可能会建议仍然对未发现的案例进行明确的例外处理。

啊 - 而且,我必须说在很多场景中都可以避免切换案例......通过将案例直接绑定为Enum值的方法(覆盖抽象方法) ,或通过实施visitor pattern

以下是如何重新实现枚举:

default

现在我们完全避免了整个场景......现在总是归结为在编译时检测到的未实现的方法!此外,它也快得多,因为不需要进行切换/案例查找。

这可能是最终目标应该是:

  

首选编译运行时异常的时间错误。

答案 2 :(得分:0)

例外的全部内容是我们不希望它们在大多数时间发生。如果构建一个健壮的大型应用程序,您应该始终编写以有意义的方式处理异常,中止应用程序正在尝试的任何子任务,并继续以不依赖于任何代码的方式成功。< / p>

但是,如果您正在构建更轻量级的东西,可以在出现问题时退出,那么捕获并重新抛出已检查的异常作为未经检查的异常(通常为RuntimeException)可以让您快速编写代码不用担心代码中到处传播的已检查异常。

这不仅仅是一个不期待它现在发生的情况,而是未来的良好实践。基础实现可能会发生变化,假设无法抛出异常的代码可能会因其他类中的更改而突然变得有能力。最糟糕的事情是吞下异常;至少,确保将它们打印到日志和/或控制台。