【问题标题】:Exiting a try block using break/continue in Java在 Java 中使用 break/continue 退出 try 块
【发布时间】:2013-04-13 02:51:47
【问题描述】:

在 Java 文档中,我正在阅读以下内容: finally 块总是在 try 块退出时执行。这样可以确保即使发生意外异常也会执行 finally 块。但是 finally 不仅仅对异常处理有用——它允许程序员避免清理代码被 return、continue 或 break 意外绕过。

你什么时候会通过 break 或 continue 退出 try 块?我能想到的唯一场景是您在 try 块内运行循环,然后使用 break/continue 退出,但这应该只是退出循环而不是 try 块本身,对吗?

【问题讨论】:

    标签: java


    【解决方案1】:

    你什么时候会退出 try 块并中断或继续?

    当你有一个try 一个循环;例如

     for (Cat cat : cattery) {
         try {
              cat.removeFromCage();
              cat.healthCheck();
              if (cat.isPedigree()) {
                  continue;
              }
              cat.spey();
         } finally {
              cat.putBackInCage();
         }
     }
    

    好的……所以有更优雅的方式来编写“代码”……但这只是一个例子。

    我能想到的唯一场景是您在 try 块内运行循环,然后使用 break/continue 退出,但这应该只是退出循环而不是 try 块本身,对吗?

    没错。


    FWIW,任何涉及中断 try 块或从 catch 或 finally 或任何其他“边缘情况”事物返回的代码都应该被简化。 JLS 清楚地指定了在这些场景中会发生什么……但这并不意味着您应该在实际程序中使用它们。

    【讨论】:

      【解决方案2】:

      Java 有标签。并且标签通常与 break 和 continue 运算符一起使用。所以,代码:

      outer: for (int i=0; i < 1; i++){
        for (int j = 0; j < 1; j++) { 
          System.out.println("j:"+j);
          continue outer;
        }
        System.out.println("i:"+i);
      }
      

      将只打印“j:0”

      因为 break 和 continue 是“标记的”,你可以在循环块内使用“try”语句,在该块内你可以尝试调用“continue”或“break outer_loop”。但正如您的引文中所述,“finally”语句阻止了该退出。

      【讨论】:

      • 您的意思是finally 的存在会阻止使用内部try/catch 打破循环?
      • @AquariusPower,我的意思是,链接处的代码:pastebin.com/M76QKXNf 将打印两个打印件。所以我已经证明了break/continue语句可以实现到任何块,而不仅仅是“父”块到“尝试”块。换句话说,问题的作者不知道 break&continue 可以有一个“参数”。
      • 使用标签不是一个好习惯。即使 Java 允许您这样做。各种循环结构可以实现相同的目标并使您的代码更具可读性。
      【解决方案3】:

      举一个完全人为的例子:

      import java.io.*;
      
      public class Foo {
          public static void main(String[] args) throws IOException {
              for (int i = 0; i < 10; i++) {
                  File file = new File("file-" + i);
                  FileWriter out = null;
                  try {
                      out = new FileWriter(file);
                      if (file.exists()) return;
                      out.write("Number " + i);
                      if (i % 2 == 0) continue;
                      else if (i % 3 == 0) break;
                  } catch (IOException e) {
                      throw new RuntimeException(e);
                  } finally {
                      out.close();
                  }
              }
          }
      }
      

      很自然,您可能希望在 try 中返回、中断或继续(或抛出异常)。在这个例子中,如果 finally 不能保证执行,就会发生资源泄漏。

      是的,try-with-resource in JDK7 解决了这个特殊问题。

      【讨论】:

        【解决方案4】:

        是的,break/continue 应该只影响循环,而不是 try/catch/finally 块。该文档只是指出,在尝试处理异常时很容易意外错过(不执行)清理代码块,尤其是那些偷偷摸摸的 breaks 和 continues 会改变流程!

        finally block should always be executed,除非 System.exit() 被调用或 JVM 崩溃!

        【讨论】:

          【解决方案5】:

          可以,使用 break 语句,我们可以在 label 的帮助下退出 try 块不使用循环

          tryLabel:
                  try {
                      if(true)
                          break tryLabel;
                      System.out.println("try");
                  }catch(Exception e) {
                      System.out.println("catch");
                      e.printStackTrace();
                  }finally{
                      System.out.println("finally");
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-09
            • 1970-01-01
            • 1970-01-01
            • 2018-08-28
            • 1970-01-01
            • 2011-05-25
            相关资源
            最近更新 更多