本篇内容主要讲解“为什么不使用try-catch-finally处理Java异常”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“为什么不使用try-catch-finally处理Java异常”吧!
一、前言
在正式分析之前,我们先看一波finally的执行顺序。
1、finally不是必要条件
也就是说try-catch-finally中,可以只有try-catch,也可以只有try-finally。
2、假设基于try-catch-finally:
第一:代码没有异常
执行顺序:try执行完整->catch不执行->finally执行
第二:代码有异常且catch进行捕获
执行顺序:try执行部分->跳转catch捕获处理->finally执行
第三:代码有异常且catch不捕获:这种情况没有catch
执行顺序:try执行部分->finally执行
从上面的执行顺序可以看出,finally语句不管在哪种情况是一定会执行的。基于这个认识,现在我们再来分析。
二、try-finally的缺点
先看案例,本案例来自《Effective java》,现在要关闭资源:
static String firstLineOfFile(String path) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(path)); try { return reader.readLine(); } finally { reader.close(); } }
关闭一个资源还好,但是如果再添加第二个资源,代码看起来就会一团糟了。
static void copy(String src, String desc) throws IOException { InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(desc); byte[] bytes = new byte[1024]; int n; try { while ((n = in.read(bytes)) != -1) { out.write(bytes, 0, n); } } finally { out.close(); } } finally { in.close(); } }
如果需要关闭的资源不仅种类多,而且数量也很多。那代码可就太庞大了。现在对这种方式的缺点进行一波总结:
1. 关闭的资源多事,代码复杂
2. 对于第一个案例,如果设备出现异常,那么那么调用readLine就会抛出异常,同时close方法也出现异常,在这种情况下,close异常会完全抹去readLine异常。在异常堆栈轨迹中也完全没有readLine异常的记录。
现在来测试一边:
基于以上原因,出现了try-with-resources。
三、try-with-resources的优势
try-with-resources是在jdk1.7引入的,可以完美解决以上的问题。要使用这个构造的资源,必须先实现AutoCloseable接口,其中包含了单个返回void的close方法,Java类库与第三方类库中的许多类和接口,现在都实现或扩展了AutoCloseable接口,因此我们现在不必实现了。
既然try-with-resources能够解决以上的问题,现在来看一下,如何解决的:
1、代码复杂问题解决
static void copy(String src, String desc) throws IOException { try (InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(desc)) { byte[] bytes = new byte[1024]; int n; while ((n = in.read(bytes)) != -1) { out.write(bytes, 0, n); } } }
可以看出这种方式代码更加简单,出现了错误,也能快速定位。
2、异常抹去问题解决
static String firstLineOfFil (String path) throws IOException { try (BufferedReader reader = new BufferedReader(new FileReader(path))) { return reader.readLine(); } }
如果readLine和不可见的close方法都抛出异常,close方法抛出的异常就会被禁止,try-finally处理机制中我们无法看到,堆栈轨迹中也不能打印,但是try-with-resources不一样,全部会被打印在堆栈轨迹中,并注明它们是被禁止的异常,通过编写调用getSuppressed方法还可以访问到它们。现在再来测试一遍。
OK,上面基本上全部分析完毕,但是此书还给出了一个更好的案例:
static String firstLineOfFile(String path, String defaultVal) { try (BufferedReader reader = new BufferedReader(new FileReader(path))) { return reader.readLine(); } catch (IOException e) { return defaultVal; } }
这个firstLineOfFile方法没有抛出异常,但是如果它无法打开文件,或者无法从中读取,就会返回一个默认值。
到此,相信大家对“为什么不使用try-catch-finally处理Java异常”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。