有一句这样话:一个衡量Java设计师水平和开发团队纪律性的好方法就是读读他们应用程序里的异常处理代码。
本文主要讨论开发Java程序时,如何设计异常处理的代码,如何时抛异常,捕获到了怎么处理,而不是讲异常处理的机制和原理。
在我自己研究Java异常处理之前,我查过很多资料,翻过很多书藉,试过很多搜索引擎,换过很多英文和中文关键字,但是关于异常处理设计的文章实在太少,在我研究完Java异常处理之后,我面试过很多人,也问过很多老员工,极少碰到对Java异常有研究的人,看来研究这个主题的人很少,本文内容本是个人研究异常时做的笔记,现整理一下与大家一起分享。
首先我们简单的回顾一下基础知识,Java中有两种异常,严格的说是三种,包含四个类,层次图如下:
捕获到了编译时异常怎么处理:
这个话题恐怖是最古老的啦,网上的文章多数都是讨论这个话题,但这些文章大部分只是给了几条禁止的原则,他们是:1)不要直接忽略异常;2)不要用try-catch包住过多语句;3)不要用异常处理来处理程序的正常控制流;4)不要随便将异常迎函数栈向上传递,能处理尽量处理。他们都对,但是要做异常处理的设计,信息还是不够,比如第一条他只是告诉了不要忽略,但没有告诉我们怎么处理,所以很多人直接e.printStackTrace()了,这种处理比直接忽略是好一点,但还不够好。对于第二条,他的理由是避免耗资源很大,不过“过多语句”这句话描述的太模糊了,没说明到底多少才算过多,以致于很多人的try-catch语句只包住会抛编译时异常的那一行代码,如果一段代码中有多行代码会抛编译时异常,那这一段代码中可能有多个try-catch语句块,像这样:
1 LLJTran llj = new LLJTran(file); 2 try { 3 llj.read(LLJTran.READ_INFO,true); 4 } catch (LLJTranException e) { 5 // ... 6 } 7 8 // ... 9 10 OutputStream out = null; 11 try { 12 File out = new File(file.getPath()+"_bak.jpg"); 13 llj.xferInfo(null, out, LLJTran.REPLACE, LLJTran.REPLACE); 14 } catch (IOException e) { 15 // ... 16 } 17 18 // ... 19 20 try { 21 out.close(); 22 } catch (IOException e) { 23 // ... 24 }