发生异常时在try块中执行其余代码

时间:2020-05-19 11:21:00

标签: 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块的line2中遇到了异常,即使这样我也需要执行line3和line4(这又会引发异常)。有没有一种简单的方法可以代替多个try-catch块。

2 个答案:

答案 0 :(得分:1)

如果需要,可以在外部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;
}

答案 1 :(得分:1)

try with resource语句允许以简洁的语法(与嵌套的finally块相比)指定即使在特殊情况下也应执行的动作。它还具有另一个优点:当多个操作失败时,异常不会相互影射,而是在主要的可抛出对象处注册为suppressed可抛出对象。缺点是资源是按照创建时的相反顺序关闭的,因此我们必须反转行的顺序:

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");
}

此示例程序在所有可能的情况下运行。我缩短了输出以仅显示一些示例:

Test 0
line1 executed
line2 executed
line3 executed
line4 executed

Test 1
letting line 1 fail
line2 executed
line3 executed
line4 executed
got exception java.lang.RuntimeException: line 1 failed
    at SafeActions.line1(SafeActions.java:23)
    at SafeActions.main(SafeActions.java:10)
Test 9
letting line 1 fail
line2 executed
line3 executed
letting line 4 fail
got exception java.lang.RuntimeException: line 1 failed
    at SafeActions.line1(SafeActions.java:23)
    at SafeActions.main(SafeActions.java:10)
    Suppressed: java.lang.RuntimeException: line 4 failed
        at SafeActions.line4(SafeActions.java:41)
        at SafeActions.lambda$main$0(SafeActions.java:7)
        at SafeActions.main(SafeActions.java:7)
Test 15
letting line 1 fail
letting line 2 fail
letting line 3 fail
letting line 4 fail
got exception java.lang.RuntimeException: line 1 failed
    at SafeActions.line1(SafeActions.java:23)
    at SafeActions.main(SafeActions.java:10)
    Suppressed: java.lang.RuntimeException: line 2 failed
        at SafeActions.line2(SafeActions.java:29)
        at SafeActions.lambda$main$2(SafeActions.java:9)
        at SafeActions.main(SafeActions.java:7)
    Suppressed: java.lang.RuntimeException: line 3 failed
        at SafeActions.line3(SafeActions.java:35)
        at SafeActions.lambda$main$1(SafeActions.java:8)
        at SafeActions.main(SafeActions.java:7)
    Suppressed: java.lang.RuntimeException: line 4 failed
        at SafeActions.line4(SafeActions.java:41)
        at SafeActions.lambda$main$0(SafeActions.java:7)
        at SafeActions.main(SafeActions.java:7)

直接使用AutoCloseable接口的一个缺点是,它声明可能抛出Exception,因此迫使我们抓住Exception。如果操作未引发检查异常或非常特殊的类型,则创建扩展AutoCloseable的自己的功能接口(对于IOException,已经有java.io.Closeable)很有用。 / p>

interface MyAction extends AutoCloseable {
    @Override public void close();
}    
public static void main(String[] args) {
    int currentTest = 11;

    try(MyAction c1 = () -> line4(currentTest);
        MyAction c2 = () -> line3(currentTest);
        MyAction c3 = () -> line2(currentTest)) {
        line1(currentTest);
    }
}

由于该示例未捕获异常,因此我还删除了无论如何在第二次迭代之后都不会执行的循环。

letting line 1 fail
letting line 2 fail
line3 executed
letting line 4 fail
Exception in thread "main" java.lang.RuntimeException: line 1 failed
    at SafeActions.line1(SafeActions.java:17)
    at SafeActions.main(SafeActions.java:11)
    Suppressed: java.lang.RuntimeException: line 2 failed
        at SafeActions.line2(SafeActions.java:23)
        at SafeActions.lambda$main$2(SafeActions.java:10)
        at SafeActions.main(SafeActions.java:8)
    Suppressed: java.lang.RuntimeException: line 4 failed
        at SafeActions.line4(SafeActions.java:35)
        at SafeActions.lambda$main$0(SafeActions.java:8)
        at SafeActions.main(SafeActions.java:8)