'try(A a = new A())' VS 'try finally'
程序员文章站
2022-06-20 17:20:01
实现了AutoCloseable接口的类,可以在try的时候直接实例化对象。try代码块完成之后,自动调用close方法,相当于在finally里主动调用。但是出现异常后的流程和try finally有什么不同呢? 下面写代码测试一下。 首先定义一个类Cat,实现AutoCloseable接口 我们 ......
实现了autocloseable接口的类,可以在try的时候直接实例化对象。try代码块完成之后,自动调用close方法,相当于在finally里主动调用。但是出现异常后的流程和try finally有什么不同呢? 下面写代码测试一下。
首先定义一个类cat,实现autocloseable接口
class cat implements autocloseable{ void sayhello() throws exception { utils.println("calling sayhello(), i will throw an exception"); throw new exception("exception in sayhello() "); } @override public void close() throws exception { utils.println("i'm closing, i will throw an exception"); throw new exception("exception in close()"); } }
我们的这个cat有以下特点:
- sayhello方法会抛出异常
- close方法也会抛出异常
test v1: 'try(cat cat = new cat())' vs 'try finally'
没有catch(不要被外层的catch迷惑,那只是为了打印异常)
static void testv1(){ utils.println("----try(cat cat = new cat())-----"); try{ try(cat cat = new cat()){ cat.sayhello(); } }catch (exception e){ utils.println("cache error in main (" + e + "), let's see its stack trace"); utils.printstacktrace(e); } utils.println("--------------"); utils.println("----try finally-----"); try{ cat cat = null; try{ cat = new cat(); cat.sayhello(); }finally { if(cat != null){ cat.close(); } } }catch (exception e){ utils.println("cache error in main (" + e + "), let's see its stack trace"); utils.printstacktrace(e); } utils.println("--------------"); }
结果输出:
----test v1---------------------------------------- ----try(cat cat = new cat())----- calling sayhello(), i will throw an exception i'm closing, i will throw an exception cache error in main (java.lang.exception: exception in sayhello() ), let's see its stack trace java.lang.exception: exception in sayhello() at cat.sayhello(cat.java:4) at test.testv1(test.java:16) at test.main(test.java:4) suppressed: java.lang.exception: exception in close() at cat.close(cat.java:10) at test.testv1(test.java:17) ... 1 more -------------- ----try finally----- calling sayhello(), i will throw an exception i'm closing, i will throw an exception cache error in main (java.lang.exception: exception in close()), let's see its stack trace java.lang.exception: exception in close() at cat.close(cat.java:10) at test.testv1(test.java:33) at test.main(test.java:4) --------------
结论
- try(cat cat = new cat())
- try代码块完成之后会自动调用close
- close抛出的异常,被suppressed了,外层捕获的只有sayhello的异常,但通过堆栈可以找到这个suppressed的异常
- try finally
- 外层捕获的是在finally执行close时抛出的异常,sayhello的异常完全不见了。
test v2: 'try(cat cat = new cat()) catch{}' vs 'try catch finally'
有catch,并且catch里再抛出异常
static void testv2(){ utils.println("----try(cat cat = new cat()) catch-----"); try{ try(cat cat = new cat()){ cat.sayhello(); } catch (exception e) { utils.println("cached err (" + e.getmessage() + "), i will throw an exception again"); throw new exception("exception in catch", e); } }catch (exception e){ utils.println("cache error in main (" + e + "), let's see its stack trace"); utils.printstacktrace(e); } utils.println("-----------------------------------------"); utils.println("----try catch finally--------------------"); try{ cat cat = null; try{ cat = new cat(); cat.sayhello(); } catch (exception e) { utils.println("cached err (" + e.getmessage() + "), i will throw an exception again"); throw new exception("exception in catch", e); }finally { if(cat != null){ cat.close(); } } }catch (exception e){ utils.println("cache error in main (" + e + "), let's see its stack trace"); utils.printstacktrace(e); } utils.println("-------------------------------------------"); }
结果输出
----test v2------ ----try(cat cat = new cat()){} catch{}----- calling sayhello(), i will throw an exception i'm closing, i will throw an exception cached err (exception in sayhello() ), i will throw an exception again cache error in main (java.lang.exception: exception in catch), let's see its stack trace java.lang.exception: exception in catch at test.testv2(test.java:50) at test.main(test.java:8) ----------------------------------------- ----try catch finally-------------------- calling sayhello(), i will throw an exception cached err (exception in sayhello() ), i will throw an exception again i'm closing, i will throw an exception cache error in main (java.lang.exception: exception in close()), let's see its stack trace java.lang.exception: exception in close() at cat.close(cat.java:10) at test.testv2(test.java:70) at test.main(test.java:8) ------------------------------------------- ---------------------------------------------------------------------
结论
- try(cat cat = new cat()) catch
- catch之前就调用了close(符合try代码块完成之后会自动调用close这个结论)
- catch到的是sayhello的异常,close抛出的异常依然被suppressed了
- catch中再次抛出的异常被外层捕获
- try catch finally
- 先走catch,再走finally,所以catch捕获的是sayhello的异常
- catch中再次抛出的异常不见了,外层捕获的是在finally执行close时抛出的异常。
测试代码地址:https://github.com/kongxiangxin/pine/tree/master/auto-closeable
推荐阅读
-
Python中的异常处理try/except/finally/raise用法分析
-
对python中的try、except、finally 执行顺序详解
-
try-catch-finally 与返回值的修改
-
'try(A a = new A())' VS 'try finally'
-
Python中的异常处理try/except/finally/raise用法分析
-
实例解析js中try、catch、finally的执行规则
-
对python中的try、except、finally 执行顺序详解
-
C#异常处理中try和catch语句及finally语句的用法示例
-
Java中try..catch..finally语句的使用
-
对try catch finally的理解