[英]execute remaining code in try block in case of exception
I have the following code:我有以下代码:
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;
}
I need to execute all 4 lines inside try block even in case of exception from above lines.即使上面的行出现异常,我也需要在 try 块中执行所有 4 行。
Suppose the code encountered an exception in line2 of try block, even then I need to execute line3 and line4(which in turn can throw exceptions).假设代码在 try 块的 line2 中遇到异常,即使这样我也需要执行 line3 和 line4(这反过来又会抛出异常)。 Is there an easy way to do this instead of having multiple try-catch blocks.
有没有一种简单的方法来代替拥有多个 try-catch 块。
You can have try/catch blocks within the outer try/catch block if it makes sense to.如果有意义的话,您可以在外部 try/catch 块中包含 try/catch 块。 Something like this:
像这样的东西:
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;
}
The try with resource statement allows to specify actions that ought be executed even in the exceptional case, with a concise syntax (compared to nested finally
blocks). try with resource语句允许使用简洁的语法(与嵌套的
finally
块相比)指定即使在例外情况下也应该执行的操作。 It also has another advantage: when multiple actions fail, the exceptions do not shadow each other but get registered as suppressed throwables at the primary throwable.它还有另一个优点:当多个操作失败时,异常不会相互影响,而是在主 throwable 上注册为抑制的 throwable。 A drawback is that resources are closed in the opposite order they were created, so we have to reverse the order of the lines:
一个缺点是资源的关闭顺序与创建它们的顺序相反,因此我们必须颠倒这些行的顺序:
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");
}
This example program runs through all possible scenarios.此示例程序贯穿所有可能的场景。 I shortened the output to show only some of the examples:
我缩短了 output 以仅显示一些示例:
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)
A disadvantage of using the AutoCloseable
interface directly, is that it declares to potentially throw Exception
and hence, forces us to catch Exception
.直接使用
AutoCloseable
接口的一个缺点是它声明可能抛出Exception
,因此迫使我们捕获Exception
。 If the actions don't throw checked exception or a very specific type, it's useful to create your own functional interface extending AutoCloseable
(In case of IOException
, there is already java.io.Closeable
).如果操作没有抛出检查异常或非常特定的类型,则创建自己的扩展
AutoCloseable
的功能接口很有用(在IOException
的情况下,已经有java.io.Closeable
)。
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);
}
}
Since this example doesn't catch exceptions, I also removed the loop which wouldn't get executed past the second iteration anyway.由于这个例子没有捕获异常,我还删除了在第二次迭代之后不会执行的循环。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.