Java 在异常情况下执行try块中的剩余代码

Java 在异常情况下执行try块中的剩余代码,java,exception,try-catch,Java,Exception,Try Catch,我有以下代码: try{ line1; // can throw exception line2; // can throw exception line3; // can throw exception line4; // can throw exception }catch(Exception e){ handle exception; }finally{ do remaining stuffs; } 我需要执行try块中的所有4行,即使在上面的行出现异常的情况下

我有以下代码:

try{
  line1; // can throw exception
  line2; // can throw exception
  line3; // can throw exception
  line4; // can throw exception
}catch(Exception e){
   handle exception;
}finally{
  do remaining stuffs;
}
我需要执行try块中的所有4行,即使在上面的行出现异常的情况下也是如此


假设代码在try块的第2行遇到异常,即使如此,我仍然需要执行第3行和第4行(这反过来会引发异常)。有没有一种简单的方法来实现这一点,而不是使用多个try-catch块

如果有必要,可以在外部try/catch块中包含try/catch块。大概是这样的:

try{
  line1; // can throw exception
  try {
    line2; // can throw exception
  } catch (Exception e) {
    if (e is a really bad one) throw e;  // don't continue
    else System.out.println("line2 failed but I'll keep going");
  }
  try {
    line3; // can throw exception
  } catch (Exception e) {
    if (e is a really bad one) throw e;  // don't continue
    else System.out.println("line3 failed but I'll keep going");
  }
  line4; // can throw exception
}catch(Exception e){
   handle exception;
}finally{
  do remaining stuffs;
}

如果有必要,可以在外部try/catch块中包含try/catch块。大概是这样的:

try{
  line1; // can throw exception
  try {
    line2; // can throw exception
  } catch (Exception e) {
    if (e is a really bad one) throw e;  // don't continue
    else System.out.println("line2 failed but I'll keep going");
  }
  try {
    line3; // can throw exception
  } catch (Exception e) {
    if (e is a really bad one) throw e;  // don't continue
    else System.out.println("line3 failed but I'll keep going");
  }
  line4; // can throw exception
}catch(Exception e){
   handle exception;
}finally{
  do remaining stuffs;
}
该语句允许使用简洁的语法(与嵌套的
finally
块相比)指定即使在特殊情况下也应该执行的操作。它还有另一个优点:当多个操作失败时,异常不会相互影响,而是在主可丢弃文件中注册为可丢弃文件。一个缺点是资源的关闭顺序与创建顺序相反,因此我们必须颠倒行的顺序:

public static void main(String[] args) {
    for(int test = 0; test < 16; test++) {
        int currentTest = test;
        System.out.println("Test "+currentTest);

        try(AutoCloseable c1 = () -> line4(currentTest);   // 4
            AutoCloseable c2 = () -> line3(currentTest);   // 3
            AutoCloseable c3 = () -> line2(currentTest)) { // 2
            line1(currentTest);                            // 1
        }
        catch(Exception ex) {
            System.out.print("got exception ");
            ex.printStackTrace(System.out);
        }

        System.out.println();
    }
}
public static void line1(int whichTest) {
    if((whichTest & 1) != 0) {
        System.out.println("letting line 1 fail");
        throw new RuntimeException("line 1 failed");
    } else System.out.println("line1 executed");
}
public static void line2(int whichTest) {
    if((whichTest & 2) != 0) {
        System.out.println("letting line 2 fail");
        throw new RuntimeException("line 2 failed");
    } else System.out.println("line2 executed");
}
public static void line3(int whichTest) {
    if((whichTest & 4) != 0) {
        System.out.println("letting line 3 fail");
        throw new RuntimeException("line 3 failed");
    } else System.out.println("line3 executed");
}
public static void line4(int whichTest) {
    if((whichTest & 8) != 0) {
        System.out.println("letting line 4 fail");
        throw new RuntimeException("line 4 failed");
    } else System.out.println("line4 executed");
}
测试9
让1号线失败
第2行已执行
第3行已执行
让4号线失败
获取异常java.lang.RuntimeException:第1行失败
在SafeActions.line1(SafeActions.java:23)
位于SafeActions.main(SafeActions.java:10)
抑制:java.lang.RuntimeException:第4行失败
在SafeActions.line4(SafeActions.java:41)
在SafeActions.lambda$main$0(SafeActions.java:7)
位于SafeActions.main(SafeActions.java:7)
测试15
让1号线失败
让2号线失败
让3号线失败
让4号线失败
获取异常java.lang.RuntimeException:第1行失败
在SafeActions.line1(SafeActions.java:23)
位于SafeActions.main(SafeActions.java:10)
抑制:java.lang.RuntimeException:第2行失败
在SafeActions.line2(SafeActions.java:29)
位于SafeActions.lambda$main$2(SafeActions.java:9)
位于SafeActions.main(SafeActions.java:7)
抑制:java.lang.RuntimeException:第3行失败
在SafeActions.line3(SafeActions.java:35)
在SafeActions.lambda$main$1(SafeActions.java:8)
位于SafeActions.main(SafeActions.java:7)
抑制:java.lang.RuntimeException:第4行失败
在SafeActions.line4(SafeActions.java:41)
在SafeActions.lambda$main$0(SafeActions.java:7)
位于SafeActions.main(SafeActions.java:7)
直接使用
AutoCloseable
接口的一个缺点是,它声明可能引发
Exception
,因此迫使我们捕获
Exception
。如果操作没有抛出选中的异常或非常特定的类型,那么创建自己的功能接口来扩展
AutoCloseable
(在
IOException
的情况下,已经有
java.io.Closeable

因为这个例子没有捕获异常,所以我还删除了循环,该循环无论如何都不会在第二次迭代后执行

让第1行失败
让2号线失败
第3行已执行
让4号线失败
线程“main”java.lang.RuntimeException中出现异常:第1行失败
在SafeActions.line1(SafeActions.java:17)
位于SafeActions.main(SafeActions.java:11)
抑制:java.lang.RuntimeException:第2行失败
在SafeActions.line2(SafeActions.java:23)
位于SafeActions.lambda$main$2(SafeActions.java:10)
位于SafeActions.main(SafeActions.java:8)
抑制:java.lang.RuntimeException:第4行失败
在SafeActions.line4(SafeActions.java:35)
在SafeActions.lambda$main$0(SafeActions.java:8)
位于SafeActions.main(SafeActions.java:8)
该语句允许使用简洁的语法(与嵌套的
finally
块相比)指定即使在特殊情况下也应该执行的操作。它还有另一个优点:当多个操作失败时,异常不会相互影响,而是在主可丢弃文件中注册为可丢弃文件。一个缺点是资源的关闭顺序与创建顺序相反,因此我们必须颠倒行的顺序:

public static void main(String[] args) {
    for(int test = 0; test < 16; test++) {
        int currentTest = test;
        System.out.println("Test "+currentTest);

        try(AutoCloseable c1 = () -> line4(currentTest);   // 4
            AutoCloseable c2 = () -> line3(currentTest);   // 3
            AutoCloseable c3 = () -> line2(currentTest)) { // 2
            line1(currentTest);                            // 1
        }
        catch(Exception ex) {
            System.out.print("got exception ");
            ex.printStackTrace(System.out);
        }

        System.out.println();
    }
}
public static void line1(int whichTest) {
    if((whichTest & 1) != 0) {
        System.out.println("letting line 1 fail");
        throw new RuntimeException("line 1 failed");
    } else System.out.println("line1 executed");
}
public static void line2(int whichTest) {
    if((whichTest & 2) != 0) {
        System.out.println("letting line 2 fail");
        throw new RuntimeException("line 2 failed");
    } else System.out.println("line2 executed");
}
public static void line3(int whichTest) {
    if((whichTest & 4) != 0) {
        System.out.println("letting line 3 fail");
        throw new RuntimeException("line 3 failed");
    } else System.out.println("line3 executed");
}
public static void line4(int whichTest) {
    if((whichTest & 8) != 0) {
        System.out.println("letting line 4 fail");
        throw new RuntimeException("line 4 failed");
    } else System.out.println("line4 executed");
}
测试9
让1号线失败
第2行已执行
第3行已执行
让4号线失败
获取异常java.lang.RuntimeException:第1行失败
在SafeActions.line1(SafeActions.java:23)
位于SafeActions.main(SafeActions.java:10)
抑制:java.lang.RuntimeException:第4行失败
在SafeActions.line4(SafeActions.java:41)
在SafeActions.lambda$main$0(SafeActions.java:7)
位于SafeActions.main(SafeActions.java:7)
测试15
让1号线失败
让2号线失败
让3号线失败
让4号线失败
获取异常java.lang.RuntimeException:第1行失败
在SafeActions.line1(SafeActions.java:23)
位于SafeActions.main(SafeActions.java:10)
抑制:java.lang.RuntimeException:第2行失败
在SafeActions.line2(SafeActions.java:29)
位于SafeActions.lambda$main$2(SafeActions.java:9)
位于SafeActions.main(SafeActions.java:7)
抑制:java.lang.RuntimeException:第3行失败
在SafeActions.line3(SafeActions.java:35)
在SafeActions.lambda$main$1(SafeActions.java:8)
位于SafeActions.main(SafeActions.java:7)
抑制:java.lang.RuntimeException:第4行失败
在SafeActions.line4(SafeActions.java:41)
在SafeActions.lambda$main$0(SafeActions.java:7)
位于SafeActions.main(SafeActions.java:7)
直接使用
AutoCloseable
接口的一个缺点是,它声明可能引发
Exception
,因此迫使我们捕获
Exception
。如果操作没有抛出选中的异常或非常特定的类型,那么创建自己的功能接口来扩展
AutoCloseable
(在
IOException
的情况下,已经有
java.io.Closeable

因为这个例子没有抓住e