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