java学习与总结-Exception

为什么需要异常

当程序运行时,如果遇到一些程序处理不了的问题,例如被除数等于0,尝试关闭不存在的流等等。在当前环境下,程序只能从当前环境跳出,把问题抛给上层的环境。

异常的流程

异常处理有两种模型:

  • 终止模型:错误非常严重,程序无法回到产生问题点继续执行。所以一旦异常被抛出,就不能回来继续执行了
  • 恢复模型:异常处理程序的工作是修正错误,然后再重新尝试调用出问题的方法,希望当异常处理后能继续执行程序。这种模型使用时就不能抛出异常,应该是调用方法来修正。

但是一般是使用终止模型,恢复模型在代码的便携和维护上相对困难和麻烦许多。

抛出异常时jvm做了什么

  1. 与创建java普通对象一样,使用new关键字在堆上创建对象
  2. 终止当前的执行路径,从当前环境中弹出堆异常对象的引用
  3. 异常处理机制接管程序
  4. 寻找一个适当的地方来继续执行程序("适当的地方"指异常处理程序)
  5. 异常处理程序将程序从错误状态下恢复执行,以使程序要么换一种方式运行(终止模型),要么继续运行下去(恢复模型)。

异常链

  • 重新抛出异常的方法 fillInStackTrace() ,在这个方法之前的栈信息会丢失,当前地址会被认为是异常的发生地
  • 构造函数的时候直接带上 上一个throwable对象,就会将异常信息继承下去,通过initCause()实现

RuntimeException如果不catch,则会一路向上,直到抛至main方法,这时候main方法会调用 e.printStackTrace(),将其错误报告输出给System.err

异常捕获

  • 如果有多个catch(),一旦其中一个catch 子句结束,则处理程序的查找过程结束
  • 异常捕获是就近原则,基类可以cover全部派生类,如果基类在派生类之前被捕获,编译器则会认为派生类的捕获永远不会执行,则编译不通过

自定义异常

派生类不能捕获基类抛出的异常


class A throw Exception1;
class B extend A throw Exception2;

try{
    A a = new B();
    a.tryThrowException();
}catch(Exception2 e){
    // 此处是无法捕获,编译时就会报unhandle excetpion
}
  1. 派生类中的方法和基类方法无关,如果upcase,需要捕获/抛出基类的异常,如果new派生类本身,则需要捕获/抛出派生类的方法。
  2. 可以理解为派生类方法和基类方法无关,看定义的是哪个对象,以定义对象的异常处理为准。
  3. 异常说明本身并不属于方法类型的一部分,方法类型是由方法的名字与参数的类型组成的。

多异常情况要注意判断异常顺序和之后执行的关系

  1. 例如打开file,需要捕获/抛出FileNotFoundException。但是读取IO内容时,可能会遇到IOException
  2. 如果遇到IOException需要将IO流close(),但是如果是FileNotFoundException则不需要close()
  3. 在close()的时候也有可能会产生异常,需要做嵌套catch。
  4. 不要在构造函数的finally里close(),这样在函数构建完成后对象不可用

finally

由于java有GC,所以不需要在finally写析构函数

  • finally的使用场景
    • 恢复除了内存之外的资源至初始状态,如已经打开的tcp连接,文件io,公共参数等。
    • 执行一些一定要执行的操作,不论是否发生异常:例如运行日志等。
  • finally总是会执行,不论throw还是return
  • 如果在需要关闭例如流,线程之类,最好使用try-finally块,finally块出现的exception就在外部catch
  • Try-With-Resources
    • Try-With-Resources会对在try子句的括号内的对象执行close()方法
    • 使用前提:必须实现java.lang.AutoCloseable
    • 如果构造函数出现异常,则jvm认为不确定是否能对这个对象进行操作,所以不会执行close()方法
 try(
    InputStream in = new FileInputStream(
                            new File("addr"));
 ){
     in.read();
 }catch(IOException e){
     // 不需要执行 in.close();
 }

总结

  1. 尽可能使用 try-with-resource。
  2. 在恰当的级别处理问题。(在知道该如何处理的情况下才捕获异常。)
  3. 解决问题并且重新调用产生异常的方法。
  4. 进行少许修补,然后绕过异常发生的地方继续执行。
  5. 用别的数据进行计算,以代替方法预计会返回的值。
  6. 把当前运行环境下能做的事情尽量做完,然后把相同的异常重抛到更高层。
  7. 把当前运行环境下能做的事情尽量做完,然后把不同的异常抛到更高层。
  8. 终止程序。
  9. 进行简化。(如果你的异常模式使问题变得太复杂,那用起来会非常痛苦也很烦人。)
  10. 让类库和程序更安全。(这既是在为调试做短期投资,也是在为程序的健壮性做长期投资。)

参考文献

部分内容引用至github内的开源翻译项目 LingCoder/OnJava8
本文只是我在拜读后的拙劣总结
传送门:https://github.com/LingCoder/OnJava8/blob/master/docs/book/15-Exceptions.md

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

推荐阅读更多精彩内容