网站首页 > java教程 正文
第十二章、异常
前言:
1、Error 和Exception 有什么区别?
2、try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
3、Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?
4、运行时异常与受检异常有何异同?
5、列出一些你常见的运行时异常?
6、final, finally, finalize 的区别?
12.1 异常
异常允许我们(如果没有其他手段)强制程序停止运行,并告诉我们出现了什么问题,或者(理想状态下)强制程序处理问题,并返回到稳定状态。
12.2 终止与恢复
异常处理理论上有两种基本模型。
终止模型:
长久以来,尽管程序员们使用的操作系统支持恢复模型的异常处理,但他们最终还是转向使用类似“终止模型”的代码,并且忽略恢复行为。
Java支持终止模型(它是Java和C++所支持的模型)。这种模型假设错误非常关键,以至于程序无法返回到异常发生的地方继续执行。
恢复模型(Java支持):
意思是异常处理程序的工作是修正错误,然后重新尝试调用出问题的方法,并认为第二次能成功。
备注:Java场景举例:try-catch exception后,再执行新的代码流程(实现从错误中恢复)。
12.3 创建自定义异常
所有标准异常都有两个构造器:
1. 默认构造器;
2. 接受字符串作为参数,以便能把相关信息放入异常对象的构造器。--Java 建议告知用户异常的具体原因信息。
// FullConstructors.java
class MyException extends Exception{ //自定义Exception建议extends Exception
public MyException(){} //默认构造器
}
public class FullConstructors{
public static void g() throws MyException{ //如外抛异常的方法,需添加申明。
System.out.println("Throwing MyException form g()");
throw new MyException("Originated in g()"); //主动抛出异常
}
public static void main(String[] args){
try{
g();
}catch(MyException e){ //捕获异常
e.printStackTrace(System.out); //栈轨迹打印
}
}
}
12.4 printStackTrace()
Throwable类声明了printStackTrace()方法(栈轨迹打印),它将打印“从方法调用处直到异常抛出处”的方法调用序列。
12.5 为异常先占个位子
可以声明方法将抛出异常,实际上却不抛出。这样做的好处是,为异常先占个位子,以后就可以抛出这种异常而不用修改已有的代码。
在编译时被强制检查的异常称为被检查的异常。
12.6 异常链
异常链:常常会想要在捕获一个异常后抛出另一个异常,并且希望把原始异常的信息保存下来,这被称为异常链。
JDK1.4以后,所有Throwable的子类在构造器中都可以接受一个cause对象作为参数。这个cause就用来表示原始异常,这样通过把原始异常传递给新的异常,使得即使在当前位置创建并了新的异常,也能通过这个异常链追踪到异常最初发生的位置。
三种带cause参数的异常:
在Throwable的子类中,只有三种基本的异常提供了带cause参数的构造器:
Error:用于Java虚拟机报告系统错误。
Exception:
RuntimeException:运行时异常
12.7 受检&不受检异常
受检异常(Checked Exception):不可在编码中忽略(必须主动处理:要么throw要么try-catch)。--会由编译器强制实施编码检测。
不受检异常(UnChecked Exception):运行时异常,RuntimeException(及其子类)类型的异常,可以在代码中忽略,RuntimeException代表的是编程错误(编译器无法检测到异常原因)。
12.8 缺憾:异常丢失
用某些特殊的方式使用finally子句,可能会丢失异常,一种简单的丢失异常的方式是从finally子句中返回。
12.9 finally子句
try-catch-finally{}代码块:一定会执行:
a. 在异常没有被当前的异常处理程序捕获的情况下,异常处理机制也会在跳到更高一层的异常处理程序之前,执行finanlly子句。
b. 当涉及break和continue语句的时候,finally子句也会得到执行。
c. finally子句会在执行return语句前执行,即它总是会执行,所以在一个方法中, 可以从多个点返回,并且可以保证重要的清理工作仍旧会执行。
d. 应用场景:比如IO.closedQuietly().
12.10 异常的限制
a. 当要覆盖方法的时候,只能抛出在基类方法的异常说明里列出的那些异常。这个限制很有用,因为这意味着,当基类使用的代码应用到其派生类对象的时候,一样能够工作。
b. 此限制只针对普通方法有效,对构造器方法无效!
c. 不能基于throw exception的类型,来区分不同的重载方法。
12.11 构造器
如果在构造器内抛出了异常,清理行为也许就不能正常工作了。--不建议在构造中throw Exception.
正确做法:嵌套使用try-catch.
12.12 异常匹配
抛出异常的时候,异常处理系统会按照代码的书写顺序抛出“最近”的处理程序。找到匹配的处理程序之后,它就认为异常将得到处理,然后就不再继续查找。
正确做法:先catch 派生类Exception,再catch基类Exception.
12.13 异常处理原则
a. "Harmful if swallowed" :不要直接吞食所有异常:
在知道如何处理Exception时,才主动catch,否则继续throw,由外层调用方负责处理。
b. 解决Exception后,再继续执行备选代码流程;
c. 只处理当前代码块的Exception,再throw其他异常(不属于当前流程的Exception),由外围代码继续处理。
12.14 总结
“报告”功能是异常的精髓所在。Java坚定地强调将所有的错误都以异常形式报告的这一事实,正是它远远超过诸如C++这类语言的长处之一,因为在C++这类语言中,需要以大量不同的方式来报告错误,或者根本就没有提供错误报告功能。
猜你喜欢
- 2024-11-06 Java核心知识3:异常机制详解(java的三种核心机制是什么)
- 2024-11-06 【Spring系列】05 自定义异常以及全局异常处理器 #java
- 2024-11-06 3种Sentinel自定义异常,你用过几种?
- 2024-11-06 关于Java Exception异常的深入用法及实例
- 2024-11-06 Java-throw异常详解以及过程(java throw exception)
- 2024-11-06 面试官:java开发中异常怎么定义好 程序员:不知道
- 2024-11-06 「译」11条Java异常处理的最佳实践
- 2024-11-06 Java入门教程十一(异常处理)(java异常处理的三种方法)
- 2024-11-06 Java,你管这叫异常?(java异常是什么意思)
- 2024-11-06 小白也能看懂的Java异常处理机制(java的异常处理机制的简单原理和应用)
你 发表评论:
欢迎- 05-16SpringBoot整合Redis实现常用功能
- 05-16基于Redis实现简单的延时消息队列
- 05-16安装Redis
- 05-16Spring系列之Redis的两种集成方式
- 05-16Django连接Redis集群问题排查思路和总结
- 05-16只需5分钟,完成Redis所有命令操作~
- 05-16熟练使用 Redis 的 5 大数据结构:Java 实战教程
- 05-16Redis 常见业务场景及实例(Java)
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)