Java编码实践、运行时异常和此场景

Java编码实践、运行时异常和此场景,java,exception,Java,Exception,在下面的场景中,我试图了解如何处理这段代码,以及它与RuntimeException的关系。我已经读到,抛出运行时异常通常比依赖静态异常要好。捕获静态检查异常并抛出未检查异常可能更好 是否存在可以捕获静态异常(可能是捕获所有异常)并仅处理该异常的场景。可能会记录错误消息并继续 在下面的代码中,在execute1方法和execute2方法中,假设存在易失性代码,您是否捕获静态异常然后重试?或者,如果存在其他错误: 如果(null==someObj){抛出新的RuntimeException();}

在下面的场景中,我试图了解如何处理这段代码,以及它与RuntimeException的关系。我已经读到,抛出运行时异常通常比依赖静态异常要好。捕获静态检查异常并抛出未检查异常可能更好

是否存在可以捕获静态异常(可能是捕获所有异常)并仅处理该异常的场景。可能会记录错误消息并继续

在下面的代码中,在execute1方法和execute2方法中,假设存在易失性代码,您是否捕获静态异常然后重试?或者,如果存在其他错误:

如果(null==someObj){抛出新的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,那么代码会退出吗

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

“检查过的异常迫使我编写毫无意义的捕获块:代码越多,越难阅读,我就越有可能弄乱重播逻辑并吃掉异常。”

有时候我不想要一个 要引发的runtimeexception,因为 然后在调用中停止执行 方法。看来我是在犯错误 在方法上,也许我可以继续。 但我会知道我是否能继续 稍后的节目

你的想法是对的。关于抛出RuntimeException的建议是,它不要求调用方使用try块或“throws”子句


如果您的代码能够从异常中恢复,那么它实际上应该捕获异常,而不是抛出任何异常。

关于异常的首要规则之一是不要滥用异常在应用程序中传递状态。它们应该用于特殊情况,而不是作为替代返回值

第二条规则是在处理异常的级别捕获异常。捕获和重新捕获并没有增加多少。方法中的任何清理代码都应该在
finally
块中完成


在我看来,捕获已检查的异常并将其作为运行时异常重新引用是对系统的滥用。感觉就像是绕过契约式设计的“限制”,而不是使用这些“限制”来获得更健壮的应用程序。

捕获异常并引发RuntimeException时,将原始异常设置为RuntimeException的原因很重要。i、 e

抛出新的RuntimeException(originalException)


否则,您首先将不知道问题出在哪里。

是处理异常还是简单地重新调用异常取决于您的用例

例如,如果您正在读取一个文件以将数据加载到应用程序中,并且发生了一些IO错误,则不太可能从错误中恢复,因此将错误重新提交到顶部并因此终止应用程序并不是一个坏的做法

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

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


例如,假设您的代码是解析文件中的配置数据。显然,可能会发生IO错误,因此您必须在代码中的某个位置捕获
IOException
。您可能无法对错误执行任何操作,因此必须重新显示它。但是,如果无法从文件中加载配置,则调用代码的人很可能能够处理此类错误,例如,通过退回到配置默认值。通过将API标记为选中的异常,使用代码的人可以清楚地看到错误可能发生的位置,从而可以在适当的位置编写错误处理代码。如果您只是简单地抛出一个
运行时异常
,那么使用您的代码的开发人员将不会意识到可能的错误,直到它们在测试过程中慢慢出现。

只有当您确定检查的异常不是预期的时,才应将检查的异常作为未检查的异常重新抛出

下面是一个典型的例子:

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);
}

我就是这么想的。互联网似乎不同意我的观点。我相信只有当运行时异常发生时,你才不在乎发生了什么。通常在应用程序中,这些构成警告。对于这两种情况,我建议抛出断言错误;从语义上讲,它似乎更合适。这只是一个基本的例子,但却是一个很好的建议:)+1。“只有在您确定不需要检查异常的情况下,才应该将检查异常作为未检查异常重新引用。”这是我通常的处理方式。但对于如何处理异常,似乎还没有一套具体的规则。我想开发者社区对此还没有决定。“仅当您确信不会出现选中的异常时才应执行。”例如…对于