1.异常的概念:
1.1为什么需要异常处理
编程时总有一些意料之外的情况发生。例如:请求某个网络资源时,突然断网了
导致连接不上;再比如数组中有3个元素,偏偏想使用第四个元素;或是妄图使用一个空引用调用方法……当程序代码无法继续执行时,必须有一种处理机制来引导程序恢复执行,这就是异常处理。
1.2异常的分类
1.2.1按继承体系分类
异常最顶层的父类是 Throwable ,它之下有两个重要子类,一个是 Error 另一个是 Exception。
其中Error 指比较严重的错误,比如内存耗尽,这时程序没有继续运行的必要。
而Exception 指还可以恢复的异常,对这类异常处理之后,程序仍可以继续运行。
1.2.2按编译分类
红色属于未检查异常,蓝色属于检查异常。
其中检查异常需要配合 try-catch 或 throws 关键字一起使用,否则会引发编译错误。
而未检查异常可以配合try-catch 或 throws 关键字,也可以不配合try-catch 或 throws 关键字,即使不配合 try-catch 或 throws 关键字,编译也不会有报错。
1.3常见异常举例
1.3.1典型的错误Error:
方法递归调用,会出现StackOverflowError:堆栈溢出的发生是因为一个应用递归太深。
当不断向堆中添加对象却不删除时,会出现OutOfMemoryError:因为内存溢出或没有可用的内存提供给垃圾回收器时,Java 虚拟机无法分配一个对象,这时抛出该异常。
1.3.2典型的异常Exception:
- Java中数组下标越界时,会引发 ArrayIndexOutofBoundsException
- 访问null的对象的方法或属性时会引发 NullPointerException
- 如果类型转换失败时会引发ClassCastException
- 遍历集合的同时remove可能会引发ConcurrentModificationException
- 除零会引发ArithmaticException
- Arrays.asList(“a”,”b”).add(“c”)` 会引发UnsupportedOperationException
2.处理异常的方法:
2.1积极处理
格式:
try {
// 有可能出现异常的代码
} catch( 异常类型 ) {
// 捕获异常后的代码
}
tips:
1. catch能捕捉的异常,要么精确匹配,要么用父类型匹配
2. 可以用多个catch捕获不同类型的异常
3. 多个catch块时,子类的catch块要写在前面,父类的catch块写在后面
4. jdk1.7 后一个catch块中可以有多个平级的异常
2.2消极处理
格式:
在方法的声明部分添加 throws 异常类型
含义: 说明方法在执行时有可能出现的异常,然后将异常交给方法的调用者处理
(其中main() 的调用者是jvm,当异常传给jvm时,程序运行就结束了)
tips:
1. 如果一个方法没有使用trycatch来处理异常,那么异常发生时,会将异常对象传递给这个方法的调用者,这时候需要在方法声明上列出可能抛出的异常。
2. 如果方法中可能出现的是检查异常,那么throws是必须的;如果方法中可能出现的只有未检查异常(RuntimeException或Error),那么throws是可选的。
3.异常的传播
以方法调用的反方向进行传播
4.自定义异常
创建异常类
class MyException extends Exception{ // 检查异常
}
class MyException extends RuntimeException { // 未检查异常
}
5.异常的使用
5.1主动抛出异常
格式:
throw new 异常对象(); // 只能是Exception或是Error的子类对象
5.2异常对象的常见方法
e.getMessage() //获取异常的信息
e.printStackTrace() //打印异常的跟踪信息
5.3异常使用的经验
5.3.1不要吞掉异常(即catch块没有代码)
5.3.2与有返回值的方法连用时要注意:
在catch也写一个return返回结果;或者把异常重新抛出
5.3.3 重写方法与异常声明(throws)
子类的重写方法不能抛出比父类更多的异常(检查异常)
子类的重写方法可以不抛出异常
tips:若父类和子类方法throws都是未检查异常则不用遵守上述约定
5.3.4建议将检查异常转换为未检查异常重新抛出
6.finally块
格式:
try {
...
} catch(Exception e) {
} finally {
// 无论出现异常与否,总会被执行的代码
}
如果try catch 以及finally都出现了return语句, 以finally中的return为准
如果try 有return, 但finally中对返回的变量做了修改, 不会影响return的结果