异常发生的原因
- 用户输入了非法数据。
- 要打开的文件不存在。
- 网络通信时连接中断,或者JVM内存溢出。
Java异常的类型
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
Java异常树
可查异常
编译器要求必须处置的异常,IOException等;
不可查异常
RuntimeException和Error。
多重捕获块,会被哪个Catch到?
按照顺序把异常抛给catch块,如果异常不匹配则继续按顺序传递,直到被捕获,或者都catch不到。
throws/throw关键字
如果一个方法没有捕获一个检查性异常,那么该方法必须使用throws关键字抛出该异常。‘
异同:
1. throws关键字在方法定义处,throw关键字在方法体;
2. throws可以抛出多个异常。
自定义异常
- 如果需要写一个检查性异常类,必须继承自Exception类
- 如果想写一个运行时异常类,需要继承自RuntimeException
finally关键字
finally语句块一定会被执行吗?
下面的情况finally语句不会执行:
- finally之前System.exit()
- 虚拟机在执行到finally之前崩溃
- 在catch语句中return数据
i的值为什么没有变?
public class Main {
public static void main(String[] args) {
int i = 10;
System.out.println(test(i));
}
private static int test(int i) {
try {
return i;
} finally {
i = 100;
System.out.println("i = "+ i);
}
}
}
输出
i = 100
10
在return语句之前finally块会先执行,i被赋值为100。但是返回却是10,这是因为return语句会缓存i的值,等finally块执行完后,返回缓存的值,也就是10。除非在finally块中添加return语句,才会返回100。