代码之家  ›  专栏  ›  技术社区  ›  Berlin Brown

Java编码实践、运行时异常和这种情况

  •  3
  • Berlin Brown  · 技术社区  · 15 年前

    在下面的场景中,我试图了解如何处理此代码以及它与RuntimeException的关系。我已经了解到,与依赖静态异常相比,抛出运行时异常通常更好。也许更好的方法是捕获静态检查异常并抛出未检查异常。

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

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

    if(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,那么代码会退出呢?

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

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

    “检查异常迫使我编写无意义的catch块:代码越多,可读性越差,我就越有可能把rethrow逻辑搞砸,并吃掉异常。”

    5 回复  |  直到 15 年前
        1
  •  15
  •   Bozho    15 年前

    当捕获异常并引发RuntimeException时,重要的是将原始异常设置为RuntimeException的原因。即

    throw new RuntimeException(originalException) .

    否则你一开始就不知道是什么问题。

        2
  •  2
  •   BalusC    15 年前

    将选中的异常重新引发为未选中的异常,只有在 当然 检查的异常不是预期的。

    下面是一个典型的例子:

    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);
    }
    
        3
  •  1
  •   Kelly S. French    15 年前

    有时我不想 将引发RuntimeException,因为 然后在调用中停止执行 方法。好像我把错误设为陷阱 在方法上,也许我可以继续。 但我会知道我是否能继续 稍后的节目。

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

    如果你的代码 可以 从异常中恢复,而不是它真正应该捕获它而不抛出任何东西。

        4
  •  1
  •   rsp    15 年前

    关于例外的第一条规则之一是不要滥用它们来在您的申请中通过状态。它们应该用于特殊情况,而不是作为可选的返回值。

    第二条规则是在处理异常的级别捕获异常。捕获和重新传输不会增加太多内容。方法中的任何清理代码都应在 finally 块。

    在我看来,捕获已检查的异常并将其作为运行时异常重新引发正在滥用系统。它感觉像是在按合同设计的“限制”周围工作,而不是使用这些“限制”来获得更健壮的应用程序。

        5
  •  1
  •   toluju    15 年前

    是否要处理一个异常,或者只是简单地重新执行它取决于您的用例。

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

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

    另外一个注意事项是,用 RuntimeException . 如果您的代码将在其他地方重用,那么检查异常以表示您的代码可能以某种方式失败是非常有帮助的。

    例如,假设您的代码是解析文件中的配置数据。显然,可能会发生IO错误,因此您必须 IOException 在你的代码中。您可能无法对错误进行任何处理,因此必须重新执行。但是,调用代码的人很可能能够处理这样的错误,例如,如果无法从文件中加载配置,则返回到配置默认值。通过将API标记为选中的异常,使用代码的人可以清楚地看到错误可能发生的位置,从而可以在适当的位置编写错误处理代码。如果你只是扔了一个 运行期异常 ,使用您的代码的开发人员将不会意识到可能的错误,除非它们在测试期间出现。