本文共 1885 字,大约阅读时间需要 6 分钟。
finally在 电脑关机、程序不再内存等非正常情况下不执行,其他情况都执行。
唯一一种在代码中导致finally不执行的情况就是
System.exit(0);
public class Demo8 { public static void main(String[] args) { haha(); } public static void haha(){ try{ int a = 10; int b = 0; System.out.println(a/b); }catch(Exception e){ //退出JVM System.out.println("出现异常"); System.exit(0);//唯一一种在代码中导致finally不执行的情况 //参数0代表正常退出,非零代表非正常退出 }finally { System.out.println("xxxxxxxxxx"); } }}
我们可以看到此时finally语句没有执行
1.输出的a是多少?
public static void main(String[] args) { int a = haha(); System.out.println(a); }public static int haha(){ int a = 10; try{ //我们只是来学习 finally ,此处并不会出现异常 return a; }catch(Exception e){ }finally { a = 20; } return 0;}
我们知道,先执行try语句再执行finally(try里面的代码不会发生异常,不会经过catch), 那么try语句里return了,finally还执行吗?
答案是执行,输出的a是10.![]()
在try语句里return a, 其实是在备份a的值,此时的a是备份的a,已经不是int a = 10 这个a了, 而在备份之后,与返回之间,finally语句执行, 修改的a是上面的a,不是备份的a, 所以备份过准备返回给方法的a不变,还是10。
2.我们再来看下面这种情况:
此时输出的p.age是多少?public static void main(String[] args) { Person p = haha(); System.out.println(p.age);//此时p.age是多少? } public static Person haha(){ Person p = new Person(); try{ p.age = 18; return p; }catch(Exception e){ return null; }finally { p.age = 28; } } static class Person{ int age; }
看了上面的内容,也许你会说p.age=28, 因为在备份p.age = 18之后与返回之间,finally语句执行将p.age修改为28修改的是备份的p.age,所以返回的Person对象p保存的age为18。
但是我们可以看到p.age被修改成了28
这是因为:Person为引用类型,备份的引用,而不是值,我们finally语句里修改的是引用里的值,在备份好的引用返回给方法的时候,这个引用里的值已经被修改了,这就是引用数据类型和基本数据类型之间的区别
下面我们看图理解
(基本数据类型保存在栈中,引用数据类型保存在堆中)![]()
![]()
转载地址:http://rjagz.baihongyu.com/