Java编码实践,运行时异常和此方案

时间:2009-11-20 21:27:58

标签: java exception

在下面的场景中,我试图了解如何处理此代码及其与Runtimexception的关系。我已经读过,通常更好的是抛出运行时异常,而不是依赖静态异常。甚至可能更好地捕获静态检查异常并抛出未经检查的异常。

是否存在可以捕获静态异常的情况,可能是catch-all Exception并且只处理异常。可能会记录错误消息并继续。

在下面的代码中,在execute1方法和execute2方法中,让我们说有易失性代码,你是否捕获静态异常然后重新抛出?或者可能还有其他错误:

if(null == someObj){throw new RuntimeException(); }

这是您使用的方法吗?

伪代码:

public class SomeWorkerObject {
  private String field1 = "";
  private String field2 = "";

  public setField1() { }
  public setField2() { }

  // Do I throw runtime exception here?
  public execute1() {
    try {
    // Do something with field 1
    // Do something with field 2
    } catch(SomeException) {
      throw new RuntimeException();
    }
  }

  // Do I throw runtime exception here?
  public execute2() {
    try {
    // Do something with field 1
    // Do something with field 2
    } catch(SomeException) {
      throw new RuntimeException();
    }

  }

}

public class TheWeb {

 public void processWebRequest() {

    SomeWorkerObject obj = new SomeWorkerObject();
    obj.setField1("something");
    obj.setField2("something");

    obj.execute1(); 
    obj.execute2();
    // Possibility that runtime exception thrown?

    doSomethingWith(obj);
 }
}

我对这段代码有几个问题。有时我不想抛出runtimeexception,因为执行在调用方法中停止。似乎我在方法中捕获错误,也许我可以继续。但我会知道我是否可以继续参加该计划。

在上面的例子中,如果obj.execute1()抛出Runtimeexception然后代码退出怎么办?

编辑:这家伙好像回答了我的很多问题,但我还是想听听你的意见。

http://misko.hevery.com/2009/09/16/checked-exceptions-i-love-you-but-you-have-to-go/

“检查过的异常迫使我写下没有意义的catch块:更多的代码,更难阅读,以及更高的机会,我将弄乱重新抛出逻辑并吃掉异常。”

5 个答案:

答案 0 :(得分:15)

当捕获异常并抛出RuntimeException时,将原始异常设置为RuntimeException的原因非常重要。即。

throw new RuntimeException(originalException)

否则你首先不会知道问题是什么。

答案 1 :(得分:2)

重新检查已检查的例外情况,因为只有在您确定不能预期检查的例外情况时才应执行未经检查的例外。

这是一个典型的例子:

try {
    hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
    // Unexpected exception. "MD5" is just hardcoded and supported.
    throw new RuntimeException("MD5 should be supported?", e);
} catch (UnsupportedEncodingException e) {
    // Unexpected exception. "UTF-8" is just hardcoded and supported.
    throw new RuntimeException("UTF-8 should be supported?", e);
}

答案 2 :(得分:1)

  

有些时候我不想要   要抛出的runtimeexception,因为   然后执行在调用中停止   方法。我似乎陷入了错误   在方法中,也许我可以继续。   但我会知道我是否可以继续   之后的节目。

你有正确的想法。关于抛出RuntimeException的建议是它不要求调用者使用try-block或'throws'子句。

如果您的代码可以从异常中恢复,那么它应该抓住它而不会抛出任何内容。

答案 3 :(得分:1)

关于例外的第一条规则之一就是不要滥用它们来在你的应用程序中传递状态。它们应该用于特殊情况,而不是替代的返回值。

第二条规则是在处理它们的级别捕获异常。捕获和重新抛出不会增加太多。方法中的任何清理代码都应该在finally块中完成。

在我看来,捕获已检查的异常并将其重新抛出为运行时异常会滥用系统。感觉就像通过合同解决设计的“局限性”而不是使用这些“限制”来获得更强大的应用程序。

答案 4 :(得分:1)

是否处理异常或只是重新抛出异常取决于您的用例。

例如,如果您正在读取文件以将数据加载到应用程序中,并且发生了一些IO错误,则您不太可能从错误中恢复,因此将错误重新抛出到顶部并因此终止应用程序是不是一个糟糕的行动方案。

相反,如果您预计可恢复的错误,那么您应该绝对捕获并处理错误。例如,您可能让用户在表单中输入数据。如果输入数据不正确,输入处理代码可能会抛出异常(例如,在解析格式错误的数字字符串时为NumberFormatException)。您的代码应捕获这些异常并向用户返回错误,提示输入正确。

另外请注意,用RuntimeException包装所有异常可能是不好的形式。如果您的代码将在其他地方重用,那么检查异常以表示您的代码可能以某种方式失败是非常有帮助的。

例如,假设您的代码是从文件中解析配置数据。显然,可能会发生IO错误,因此您必须在代码中的某处捕获IOException。您可能无法对错误做任何事情,因此您将不得不重新抛出它。但是,有人调用您的代码可能能够处理这样的错误,例如,如果无法从文件加载配置,则退回配置默认值。通过使用已检查的异常标记您的API,使用您的代码的人可以清楚地看到可能发生错误的位置,从而可以在适当的位置编写错误处理代码。如果您只是抛出一个RuntimeException,那么使用您的代码的开发人员在测试过程中不会出现可能的错误。

相关问题