重温try-catch-finally
2021-04-16 本文已影响0人
艺超51iwowo
本周一个重要的收获是自己在代码中,引入了java7的try-with-resource方法。该方法实际上用的比较少,和同事讨论的时候,有一个问题比较有趣,如果同时使用try-with-resource和finally,那资源是在finally之前关闭的,还是之后呢?
try-with-resource下finally代码块的执行顺序
示例代码如下:
注意: 使用try-with-resource的类,必须实现AutoCloseable接口。
public class TryWithResourceTest {
public static void main(String[] args) {
try (MyTest myTest = new MyTest()) {
System.out.println("main");
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("finally");
}
}
private static class MyTest implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("myTest.close");
}
}
}
执行结果如下:
image-20210321065844425可以看到,close方法是在正常的finally之前执行的,也就是之前大家广知的finally代码块是最后执行的。
finally代码块的一些其他注意事项
1. finally代码块一定会执行吗?
执行方法后,直接exit,此时finally模块无法正常执行。
image-202103210705161852. finally代码块中如果对return中的变量做了修改,那返回结果会修改吗?
2.1 先看引用类型,在MyTest类中增加String 类型的text和Integer类型的number字段,示例代码如下
private static MyTest executeReference() {
MyTest myTest = new MyTest();
try {
myTest.setText("try-return");
myTest.setNumber(10);
return myTest;
} finally {
myTest.setText("finally-return");
myTest.setNumber(20);
}
}
在finally模块中,对返回值做了修改,输出结果如下
image-20210321071707539此时,finally模块会修改try中返回的值。
2.2 但是测试发现,如果变为基本类型或者包装类型,情况又不一样
测试代码:
private static Integer executeBox() {
Integer integer = new Integer(300);
try {
return integer;
} finally {
integer = new Integer(400);
}
}
private static int executeUnBox() {
int integer = 300;
try {
return integer;
} finally {
integer = 400;
}
}
image-20210321071852239
此时的返回结果,是以try中的返回结果为准。
2.3 最后再来看一下基本类型数组的情况
private static int[] executeArray() {
int[] test = new int[] {0, 1};
try {
return test;
} finally {
test[1] = 10;
}
}
此时的测试结果,对应位置的数据已经被finally模块修改过了。
image-20210321072353664所以,
- 如果是引用类型,finally可以对其中的值进行修改。
- 如果是基本类型和其包装类型,finally不会进行修改,以try语句中的为准
3. finally代码块中如果也有return语句,那会返回什么结果呢?
针对上述情况中,基本类型和包装类型的测试代码中,直接在finally模块中,执行return语句。
private static Integer executeBox() {
Integer integer = new Integer(300);
try {
return integer;
} finally {
integer = new Integer(400);
return integer;
}
}
private static int executeUnBox() {
int integer = 300;
try {
return integer;
} finally {
integer = 400;
return integer;
}
}
此时的测试结果会是finally中最后修改的值
image-20210321072900945但是实际情况下,此时如果有安装Alibaba代码规约检查工具,会有对应的提示,这种情况容易触发问题,需引起重视。
image-20210321072954699