try catch finally 执行顺序总结

在网上看到一些异常处理的面试题,试着总结一下,先看下面代码,把这个方法在main中进行调用打印返回结果,看看结果输出什么。

public static int testBasic(){

        inti = 1;

        try{

            i++;

            System.out.println("try block, i = "+i);

        }catch(Exception e){

            i ++;

            System.out.println("catch block i = "+i);

        }finally{

            i = 10;

            System.out.println("finally block i = "+i);

        }

        return i;

}

没错,会按照顺序执行,先执行try内代码段,没有异常的话进入finally,最后返回,那么输出如下:

try block, i = 2

finally block i = 10

main test i = 10


这个没有问题,如果我们把return语句放入try catch里又会怎么样呢

public static int testBasic(){

        inti = 1;

        try{

            i++;

            System.out.println("try block, i = "+i);

            return i;

        }catch(Exception e){

            i ++;

            System.out.println("catch block i = "+i);

            return i;

        }finally{

            i = 10;

            System.out.println("finally block i = "+i);

        }

}

输出结果是:

try block, i = 2

finally block i = 10

main test i = 2


代码顺序执行从try到finally,由于finally是无论如何都会执行的,所以try里的语句并不会直接返回。在try语句的return块中,return返回的引用变量并不是try语句外定义的引用变量i,而是系统重新定义了一个局部引用i’,这个引用指向了引用i对应的值,也就是2,即使在finally语句中把引用i指向了值10,因为return返回的引用已经不是i,而是i',所以引用i的值和try语句中的返回值无关了。

但是,这只是一部分,如果把i换成包装类型而不是基本类型呢,来看看输出结果怎样,示例如下:

public static List testWrap(){

        List list =newArrayList<>();

        try{

            list.add("try");

            System.out.println("try block");

            return list;

        }catch(Exception e){

            list.add("catch");

            System.out.println("catch block");

            return list;

        }finally{

            list.add("finally");

            System.out.println("finally block ");

        }

}

打印结果如下:

try block

finally block 

main test i = [try, finally]

可以看到,finally里对list集合的操作生效了,这是为什么呢。我们知道基本类型在栈中存储,而对于非基本类型是存储在堆中的,返回的是堆中的地址,因此内容被改变了。


好了,现在我们在finally里加一个return,看看语句是从哪里返回的。

public static int testBasic(){

        inti = 1;

        try{

            i++;

            System.out.println("try block, i = "+i);

            return i;

        }catch(Exception e){

            i ++;

            System.out.println("catch block i = "+i);

            return i;

        }finally{

            i = 10;

            System.out.println("finally block i = "+i);

            return i;

        }

}

输出结果如下:

try block, i = 2

finally block i = 10

main test i = 10

可以看到,是从finally语句块中返回的。可见,JVM是忽略了try中的return语句。但IDE中会对finally中加的return有黄色警告提示,这是为什么呢,在try里加入一行会执行异常的代码,如下:

public static int testBasic(){

        inti = 1;

        try{

            i++;

            intm = i / 0 ;

            System.out.println("try block, i = "+i);

            return i;

        }catch(Exception e){

            i ++;

            System.out.println("catch block i = "+i);

            return i;

        }finally{

            i = 10;

            System.out.println("finally block i = "+i);

            return i;

        }

}

打印结果如下:

catch block i = 3

finally block i = 10

main test i = 10

可以看到,因为finally中有return语句,try、catch中的异常被消化掉了,屏蔽了异常的发生,这与初期使用try、catch的初衷是相违背的,因此编译器也会提示警告。

那如果在finally中有异常发生,会对try、catch中的异常有什么影响呢?

public static int testBasic(){

        inti = 1;

        try{

            i++;

            Integer.parseInt(null);

            System.out.println("try block, i = "+i);

            return i;

        }catch(Exception e){

            String.valueOf(null);

            System.out.println("catch block i = "+i);

            return i;

        }finally{

            i = 10;

            intm = i / 0;

            System.out.println("finally block i = "+i);

        }

}

这里我们在try、catch里强行加上异常语句,打印结果如下:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at tryandcatch.TryAndCatch.testBasic(TryAndCatch.java:25)

at tryandcatch.TryAndCatch.main(TryAndCatch.java:45)

这个提示表示的是finally里的异常信息,也就是说一旦finally里发生异常,try、catch里的异常信息即被消化掉了,也达不到异常信息处理的目的。


总结以上测试:

1、finally语句总会执行。

2、如果try、catch中有return语句,finally中没有return,那么在finally中修改除包装类型和静态变量、全局变量以外的数据都不会对try、catch中返回的变量有任何的影响(包装类型、静态变量会改变、全局变量)。

3、尽量不要在finally中使用return语句,如果使用的话,会忽略try、catch中的返回语句,也会忽略try、catch中的异常,屏蔽了错误的发生。

4、finally中避免再次抛出异常,一旦finally中发生异常,代码执行将会抛出finally中的异常信息,try、catch中的异常将被忽略。

所以在实际项目中,finally常常是用来关闭流或者数据库资源的,并不额外做其他操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,581评论 18 399
  • 废话不多说,自己进入今天的主题 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:...
    传奇内服号阅读 2,336评论 1 31
  • 我的家乡阳泉是个美丽、富饶的小山城。那里有一泻千里的娘子关瀑布,有绿树成阴的翠枫山,有风景如画的桃河公园,还...
    宝旺阅读 450评论 0 1
  • 新年第一天没记得要写点东西 经过奔波劳累回校的第二天 睡觉前写点东东 昨天和同学约出去浪了浪 而且还见了两个久违的...
    林深时见鹿有阅读 264评论 0 0
  • 昨天早读看到这样一个句子。句子中出现了两个“it”。原本没什么好奇,英文中这种“it”指代到处都是。但是老师讲到后...
    来郑坤茹阅读 568评论 1 3