【问题标题】:When to use exceptions in Java (example)何时在 Java 中使用异常(示例)
【发布时间】:2011-03-13 21:19:47
【问题描述】:

我知道这是不好的做法,尽管我知道我无法解释原因。

int [] intArr = ...
...
try{
   int i = 0;
   while(true){
      System.out.println(intArr[i++]);
   }
}catch(ArrayIndexOutOfBoundsException e){}

我认为您应该只对不应该发生的事情使用例外。我问这个问题是因为我认为我有时使用错误的异常。如果您的程序正在运行标准案例,是否应该抛出异常?

这似乎相关: Preventing exceptions vs. catching exceptions in Java

【问题讨论】:

  • 你读过 Joshua Bloch 的 Effective Java 吗?他有一个和你非常相似的代码示例,并且很好地解释了为什么不这样做。我强烈推荐阅读那本书的例外章节。

标签: java exception exception-handling


【解决方案1】:

你是对的:例外适用于,嗯,例外 情况。使用它们来控制正常的控制流不仅会掩盖代码的意图(这已经足以取消它的资格),而且速度也会慢得多,因为抛出和捕获异常的成本很高。

标准的习惯用法(在 Java5 及更高版本中)使用 foreach 循环:

for (int i : intArr) {
  System.out.println(i);
}

【讨论】:

  • +1 这就是为什么你不应该使用 Integer.Parse 如果你知道它会经常失败。例如解析 xxxxxx 数字,其中多个可能失败。相反,您会在 C# 中使用类似 int.TryParse 的东西(java 等效项)。不抛出异常时异常很快。但是当它们被抛出时,它们相当慢(使用消息创建新对象,经历大量嵌套捕获等)。
  • @Lassee 虽然我同意你的逻辑,但我不相信有 java 等效的 TryParse
【解决方案2】:

这是错误的,因为你知道最终循环会到达intArr的最后一个元素,所以这没有什么异常,你实际上是期待这种行为。

【讨论】:

    【解决方案3】:

    在涉及RuntimeException 时,捕获异常只是一种不好的做法。你试图抓住的ArrayIndexOutOfBoundsException 有一个。

    RuntimeExceptions 识别由代码流故障引起的以编程方式可恢复的问题。你不应该通过捕获它们来修复它们,而是通过编写适当的代码并使用流控制语句,如if/elsewhilefor 等。

    另见:

    【讨论】:

      【解决方案4】:

      一如既往地“视情况而定”,您会发现许多不同的意见。这是我的

      • 异常分为两大类。
        • 您可以合理预期和处理的事情 (FileNotFoundException)
        • 假设代码完美(ArrayIndexOutOfBounds),您通常不会预料到的事情

      您通常希望处理第一个类别而不是后者。后者通常是编程错误。

      您的示例属于后一种情况,即编程错误。该异常旨在提供有关运行时故障的良好信息,而不是充当控制流。

      有人会说第一个是checked exceptions,第二个是unchecked exceptions。我不同意这一点。我几乎总是发现检查的异常在现实中很痛苦,因为您几乎总是最终对另一种异常类型进行 catch/wrap/rethrow。在抛出异常和定义我自己的异常类时,我几乎总是使用 unchecked。

      【讨论】:

        【解决方案5】:

        你是对的。不应使用异常来处理流程。

        【讨论】:

          【解决方案6】:

          以你的方式吃异常通常被认为是一种不好的做法:如果你不需要做任何进一步的治疗,你可以记录它。

          【讨论】:

            【解决方案7】:

            仅在特殊情况下,例如,

            • 当一个方法不能做它应该做的事情时
            • 不控制执行流程

            【讨论】:

              【解决方案8】:

              异常应该捕获异常,记录并尽可能恢复。

              如果是正常程序流程的一部分,你应该正常处理。

              【讨论】:

                【解决方案9】:

                异常适用于代码中的异常。不适用于标准情况。

                但是,您的代码还有一个更严重的问题,如果不使用异常,它会更慢。创建异常、抛出异常和捕获异常需要额外的 CPU 和内存。

                对于只希望在错误情况下抛出异常的其他程序员来说,代码变得更难阅读。

                【讨论】:

                  【解决方案10】:

                  到达数组的末尾并不是例外情况。您在开始循环之前就知道长度,所以只需使用标准习语即可。

                  for(int i = 0; i < intArr.length; ++i) {
                      System.out.println(intArr[i]);
                  } 
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2023-03-11
                    • 2013-11-17
                    • 2013-12-16
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2014-02-12
                    • 2014-09-08
                    相关资源
                    最近更新 更多