3

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

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

4

5 回答 5

6

你什么时候会退出 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 清楚地指定了在这些场景中会发生什么……但这并不意味着您应该在实际程序中使用它们。

于 2013-04-13T03:01:11.750 回答
3

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”语句会阻止该退出。

于 2013-04-13T03:08:56.987 回答
2

对于一个完全人为的例子:

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 不能保证执行,你就会有资源泄漏。

是的,这个特殊的问题是通过JDK7 中的 try-with-resource解决的。

于 2013-04-13T03:01:12.320 回答
1

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

finally 块应该始终被执行,除非System.exit()被调用或 JVM 崩溃!

于 2013-04-13T03:01:18.217 回答
1

是的,使用break 语句,我们可以在label的帮助下退出 try 块,而无需使用 loop

tryLabel:
        try {
            if(true)
                break tryLabel;
            System.out.println("try");
        }catch(Exception e) {
            System.out.println("catch");
            e.printStackTrace();
        }finally{
            System.out.println("finally");
        }
于 2017-09-30T18:53:52.513 回答