异常Finally语句是否执行
- finally
在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生了异常,最终都要执行此段代码。
在通常情况下,finally最终都会执行此段代码,如果是程序被关闭了结束了,finally才不会执行。这个结束指的是软件在内存中没了、电脑停电关机了,如果不是这种非正常的情况,finally必然执行。
- 示例一
public class Demo01 {
public static void main(String[] args) {
test();
}
public static void test(){
try {
System.out.println("测试1");
System.out.println("测试2");
return;
}catch (Exception e){
}finally {
System.out.println("finally执行");
}
}
}
输出结果:
finally会执行,哪怕try中return了也会执行,是先执行了return,但是return执行时要先准备一个返回值,这里没有返回值也会有这个准备的过程,在准备的这个过程finally将会执行。
- 示例二
public class Demo02 {
public static void main(String[] args) {
Person person = test();
System.out.println(person.age);
}
public static Person test() {
Person person = new Person();
try {
person.age = 18;
return person;
} catch (Exception e) {
return null;
} finally {
person.age = 28;
}
}
static class Person {
int age;
}
}
输出结果:
图析:
Person引用对象
person
入栈,new Person()
在堆中开辟一段内存空间,栈中保存地址0x123
,return备份返回值,这里备份的是一段地址0x123
,在finally中改变的不是0x123,而是地址0x123中的内容,然后将age=18
改为age=28
,这也是基本数据类型和引用数据类型的区别。
- 示例三
public class Demo03 {
public static void main(String[] args) {
int a = test();
System.out.println(a);
}
public static int test() {
int a = 10;
try {
return a;
} catch (Exception e) {
} finally {
a = 20;
}
return 0;
}
}
输出结果:
图析:
首先整个方法入栈,
a=10
入栈,走到try-return a
时,备份返回值,复制a=
后面的内容,也就是10,执行finally将栈中a=10
变为a=20
,但是备份的多少数据就是多少,所以最后输出的是10。
- 示例四
public class Demo04 {
public static void main(String[] args) {
test();
}
public static void test() {
try {
int a = 20;
int b = 0;
System.out.println(a / b);
} catch (Exception e) {
System.out.println("出现异常");
//退出JVM
System.exit(0);
} finally {
System.out.println("finally测试");
}
}
}
输出结果:
因为
System.exit(0)
;退出了JVM,结束了所以finally不会执行。