首页 > 解决方案 > 如何使用异常处理来完全停止执行?

问题描述

public boolean validateInfo(Item item) throws Exception {
    StringBuilder errors = new StringBuilder();
    errors.append(Validator.validateCommonInfo(flexPayload))
          .append(Validator.validateSpecificInfo(flexPayload))
    if(errors.length() > 0) {
        throw new Exception(errors.toString());
    }
    return true;
}

上面的代码来自我正在做的一个项目。我正在解析几个项目,如果它们不包含正确的信息,我想抛出一个异常并停止一起解析这些项​​目。通过投掷throw new Exception(errors.toString());,我认为这会终止整个过程。这不是目前正在发生的事情。我对此的单元测试正在通过,但我在其他地方发现了一个错误,这表明异常并没有完全停止解析。在这里处理异常处理的最佳方法是什么?如果有错误,我不会发生任何解析。

标签: javaexception

解决方案


通过抛出 throw new Exception(errors.toString()); 我认为这会终止整个过程。

为什么你这么想?抛出异常只是通过“返回”该异常而导致当前方法退出。

异常的目的是传达操作可能失败的信息,从而为调用代码提供一种通知方式和处理方式(例如重试、回退、采用 B 计划、要求用户提供更多输入等) ...)。

事实上,根据您示例中的名称,这正是这里应该发生的事情。一些代码想要确保它item是有效的,所以它会调用你的validateItem()方法来检查。在正常情况下一切都很好,但在特殊情况下会出现问题 - 因此调用代码可以处理该问题(例如,通过向 HTTP 客户端返回 400 响应代码;通过向用户显示一个说明错误的对话框并询问他们更正;通过决定不继续缓存更新并保留以前的Item内容;或者根据它正在做的任何其他相关的事情)。

杀死整个过程绝对不是你应该做的回应无效的Item尤其不是这个级别。即使您出于某种原因确实需要终止该进程,也应该在您的main()方法(或容器的类似顶级生命周期方法)中在顶层完成。

因此,要回答您的明确问题“我如何完全停止执行”:此方法的调用者本身应该抛出一个异常以指示它无法成功执行任务(由于 invalid Item)。并且它的调用者应该抛出一个异常来指示更广泛的操作失败等,一直到堆栈的顶部。这些可以通过捕获和包装初始异常来显式抛出,也可以根本无法捕获您的异常并让它冒泡。

其他问题

  1. 您的validateInfo()方法返回boolean. 因此,我认为从其签名中假设该方法将trueInfo有效时返回,并且在无效时返回是公平false的。相反,抛出异常违反了最小意外原则。如果在这种情况下确实需要抛出异常,请让方法返回void- 没有异常则表示输入有效。
  2. 你扔(并声明你扔)一个普通的java.lang.Exception物体。由于Exception位于一个非常大的类层次结构的顶部,这也包括所有其他异常,这意味着调用者不能确定异常是由于无效项目而不是例如 a ClassNotLoadedException、 anInterruptedException或任何数量的在任何时候都可能发生的其他异常。您应该在这里抛出一个自定义异常类,或者至少使用更具体的东西,比如IllegalArgumentException.
  3. 如果有多个错误,您的消息将被混为一谈。我不会直接附加到 a StringBuider,而是整理 aList<String>错误,然后将它们与 egString.join("; ", errors)连接以生成异常的完整错误消息。

推荐阅读