20190901 On Java8 第十五章 异常
第十五章 异常
要想创建健壮的系统,它的每一个构件都必须是健壮的。
异常概念
C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pascal)。
基本异常
异常参数
所有标准异常类都有两个构造器:一个是无参构造器;另一个是接受字符串作为参数,以便能把相关信息放入异常对象的构造器。
Throwable
是异常类型的根类。
自定义异常
对异常来说,最重要的部分就是类名。
异常与记录日志
对于异常类来说,getMessage()
方法有点类似于 toString()
方法。
异常声明
不过还是有个能“作弊”的地方:可以声明方法将抛出异常,实际上却不抛出。编译器相信了这个声明,并强制此方法的用户像真的抛出异常那样使用这个方法。这样做的好处是,为异常先占个位子,以后就可以抛出这种异常而不用修改已有的代码。在定义抽象基类和接口时这种能力很重要,这样派生类或接口实现就能够抛出这些预先声明的异常。
捕获所有异常
多重捕获
通过 Java 7 的多重捕获机制,可以将不同类型的异常使用“或”将它们组合起来,只在一个 catch
块中使用:
try {
x();
} catch (Except1 | Except2 | Except3 | Except4 e) {
process();
}
栈轨迹
printStackTrace()
方法所提供的信息可以通过 getStackTrace()
方法来直接访问,这个方法将返回一个由栈轨迹中的元素所构成的数组,其中每一个元素都表示栈中的一桢。元素 0 是栈顶元素,并且是调用序列中的最后一个方法调用(这个 Throwable
被创建和抛出之处)。数组中的最后一个元素和栈底是调用序列中的第一个方法调用。
重新抛出异常
只是把当前异常对象重新抛出,那么 printStackTrace()
方法显示的将是原来异常抛出点的调用栈信息,而并非重新抛出点的信息。要想更新这个信息,可以调用 filInStackTrace()
方法,这将返回一个 Throwable
对象,它是通过把当前调用栈信息填入原来那个异常对象而建立的。调用 fillInStackTrace()
的那一行就成了异常的新发生地了。
精准的重新抛出异常
从 Java 7 开始,允许抛出更具体的异常,即 catch 中捕捉的是父类,catch 块中可以抛出子类。
异常链
在 Throwable
的子类中,只有三种基本的异常类提供了带 cause 参数的构造器。它们是 Error
(用于 Java 虚拟机报告系统错误)、Exception
以及 RuntimeException
。如果要把其他类型的异常链接起来,应该使用 initCause0
方法而不是构造器。
DynamicFieldsException dfe = new DynamicFieldsException();
dfe.initCause(new NullPointerException());
throw dfe;
Java 标准异常
Throwable
这个 Java 类被用来表示任何可以作为异常被抛出的类。Throwable
对象可分为两种类型(指从 Throwable
继承而得到的类型):Error
用来表示编译时和系统错误(除特殊情况外,一般不用你关心);Exception
是可以被抛出的基本类型,在 Java 类库、用户方法以及运行时故障中都可能抛出 Exception
型异常。所以 Java 程序员关心的基类型通常是 Exception
。
异常的基本的概念是用名称代表发生的问题,并且异常的名称应该可以望文知意。异常并非全是在 java.lang
包里定义的;有些异常是用来支持其他像 util、net 和 io 这样的程序包,这些异常可以通过它们的完整名称或者从它们的父类中看出端倪。
特例:RuntimeException
RuntimeException
类型的异常(或者任何从 RuntimeException
继承的异常),也被称为“不受检查异常”。这种异常属于错误, 代表的是编程错误,将被自动捕获。
只能在代码中忽略 RuntimeException
(及其子类)类型的异常,因为所有受检查类型异常的处理都是由编译器强制实施的。
异常限制
当覆盖方法的时候,只能抛出在基类方法的异常说明里列出的那些异常。
异常限制对构造器不起作用。
一个出现在基类方法的异常说明中的异常,不一定会出现在派生类方法的异常说明里。这点同继承的规则明显不同,在继承中,基类的方法必须出现在派生类里,换句话说,在继承和覆盖的过程中,某个特定方法的“异常说明的接口”不是变大了而是变小了——这恰好和类接口在继承时的情形相反。
Try-With-Resources 用法
Java 7 引入了 try-with-resources
语法。
在 try-with-resources
定义子句中创建的对象(在括号内)必须实现 java.lang.Autocloseable
接口,这个接口有一个方法,close()。当在 Java 7 中引入 AutoCloseable
时,许多接口和类被修改以实现它;查看 Javadocs 中的 AutoCloseable
,可以找到所有实现该接口的类列表,其中包括 Stream
对象。
规范头中定义的每个对象都会在 try 语句块运行结束之后调用 close()
方法。
Java 5 中的 Closeable
已经被修改,修改之后的接口继承了 AutoCloseable
接口。所以所有实现了 Closeable
接口的对象,都支持了 try-with-resources
特性。
不能在资源规范头中定义了一个不是 AutoCloseable
的对象。
异常匹配
抛出异常的时候,异常处理系统会按照代码的书写顺序找出“最近”的处理程序。找到匹配的处理程序之后,它就认为异常将得到处理,然后就不再继续查找。
查找的时候并不要求抛出的异常同处理程序所声明的异常完全匹配。派生类的对象也可以匹配其基类的处理程序。
其他可选方式
异常处理的一个重要原则是“只有在你知道如何处理的情况下才捕获异常"。
所有模型都是错误的,但有些是能用的。
好的程序设计语言能帮助程序员写出好程序,但无论哪种语言都避免不了程序员用它写出了坏程序。
异常指南
应该在下列情况下使用异常:
- 尽可能使用
try-with-resource
。 - 在恰当的级别处理问题。(在知道该如何处理的情况下才捕获异常。)
- 解决问题并且重新调用产生异常的方法。
- 进行少许修补,然后绕过异常发生的地方继续执行。
- 用别的数据进行计算,以代替方法预计会返回的值。
- 把当前运行环境下能做的事情尽量做完,然后把相同的异常重抛到更高层。
- 把当前运行环境下能做的事情尽量做完,然后把不同的异常抛到更高层。
- 终止程序。
- 进行简化。(如果你的异常模式使问题变得太复杂,那用起来会非常痛苦也很烦人。)
- 让类库和程序更安全。(这既是在为调试做短期投资,也是在为程序的健壮性做长期投资。)
20190901 On Java8 第十五章 异常的更多相关文章
- “全栈2019”Java异常第十五章:异常链详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- Gradle 1.12 翻译——第十五章. 任务详述
有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...
- C++ Primer Plus学习:第十五章
第十五章 友元.异常和其他 友元 友元类 表 0-1 class Tv { public: friend class Remote; } Remote类可以使用Tv的数据成员,Remote类在Tv类后 ...
- 15第十五章UDF用户自定义函数(转载)
15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布
- 《Linux命令行与shell脚本编程大全》 第十五章 学习笔记
第十五章:控制脚本 处理信号 重温Linux信号 信号 名称 描述 1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能 ...
- CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章
第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...
- Gradle 1.12用户指南翻译——第四十五章. 应用程序插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- Gradle 1.12用户指南翻译——第二十五章. Scala 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
- Gradle 1.12用户指南翻译——第三十五章. Sonar 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
随机推荐
- ubuntu下docker安装
首先来一个官网安装教程链接:https://docs.docker.com/install/linux/docker-ce/ubuntu/ 目前docker主要有docker-CE 与 docker- ...
- 微信小程序(19)-- 从底部向上滑出的动画效果
从底部向上滑出的动画效果: 用到了小程序的触摸事件bindtouchmove,以及创建一个annimation对象,完成动画操作之后使用animation这个对象的export()方法导出动画数据. ...
- python--线程锁,队列
#线程数据安全处理--同步锁 import time def sub(): global num print("ok") lock.acquire()#获取这把锁--->只有 ...
- STL的容器哈希表
C++ STL中,哈希表对应的容器是 unordered_map(since C++ 11).根据 C++ 11 标准的推荐,用 unordered_map 代替 hash_map. 与Map的区别 ...
- MUI使用h5+进行召唤各大APP应用市场调用启动的包名和方式
转载自:https://blog.csdn.net/u012442504/article/details/87367153 // 扩展API加载完毕后调用onPlusReady回调函数 documen ...
- hdu 3572 : Task Schedule (网络流)
题目链接 题意: 有M个机器,N个任务 对第i个任务,需要在[Si,Ei]这段时间内恰有Pi天被process 每天最多有M个机器同时工作 每一天,一个任务若被process,那么它恰占用一个机器. ...
- Error:MySQLAdministrator无法连接到实例
Q:利用MySQLAdministrator登录时显示could not connect to the specific instance,使用ping指令后可以ping通,如下所示: A:这里能够p ...
- 靠!老师居然叫我们去写博弈论!!!结果写了一个晚上的博弈论,简直要死QAQ。。。发发博客休息一下。。。TAT。。。
萌萌的糖果博弈 题目描述: 用糖果来引诱小朋友学习是最常用的手法,绵羊爸爸就是用糖果来引诱萌萌学习博弈的.他把糖果分成了两堆,一堆有A粒,另一堆有B粒.他让萌萌和他一起按照下面的规则取糖果:每次可以任 ...
- Vue中的MVVM框架
ViewModel:数据双向绑定 场景: 针对具有复杂交互逻辑的前段应用 提供基础的架构抽象 通过Ajax数据持久化,保证前端用户体验 什么是vue.js? 是一个轻量级的mvvm框架 数据驱动+组 ...
- inux 下zip包的压缩与解压
linux zip 命令详解 功能说明:压缩文件. 语 法:zip [-AcdDfFghjJKlLmoqrSTuvVwXyz$][-b <工作目录>][-ll][-n <字尾字符串& ...