1. 异常的定义及分类
Error:程序在运行过程中不可预料的意外情况,通常会导致JVM无法处理或无法恢复。
Exception:程序在运行过程中可预料的意外情况。
异常的分类:
所有的Error和Exception都继承自Throwable类,Exception下除了RuntimeException类及其子类是运行时异常外,其他都是编译时异常。
常见的Error:
- OutOfMemoryError(内存溢出错误)
- NoClassDefFoundError(编译加载不到类)
常见的编译时异常:
- IOException
- SQLException
- FileNotFoundException
- ClassNotFoundException
常见的运行时异常:
- ArithmeticException
- ArrayIndexOutOfBoundsException
- StringIndexOutOfBoundsException
- IllegalArgumentException
- NullPointException
2. 异常处理方式
最常见:
try…catch…finally形式
try{
...
}catch(Exception e){
...
}finally{
... // 一般情况下,finally内的代码一定会被执行,除非JVM退出(System.exit(0))。用于释放资源。
}
throws形式
public void method() throws ArithmeticException, ArrayIndexOutOfBoundsException{
if(...)
throw new ArithMeticException(); //将异常抛出让调用者处理
else{
...
}
}
注意,当throw后面的异常是编译时异常时,必须在方法申明后的throws上加入此异常。throw后面的异常是运行时异常时可以不处理。
变形:(JDK7以后出现)
多catch形式
try{
...
}catch(ArithmeticException ae){
...
}catch(ArrayIndexOutOfBoundsException be){
...
}catch(Exception e){ // 最大的异常一定要在后面
e.printStackTrace();
}finally{
...
}
或者
try{
...
}catch(ArithmeticException | ArrayIndexOutOfBoundsException ae){ // 所有的异常必须平级
...
}finally{
...
}
3. throws和throw的区别
1.throws
- throws用在方法申明后面,跟的是异常类名
- throws后面可以跟多个异常类名
- throws表示程序可能会出现后面的异常,异常由调用者处理
2.throw
- throw用在方法体内,跟的是异常类的对象
- throw后面只能跟一个异常类对象
- 运行throw方法,表示异常已经发生了。编译时异常调用者必须处理,运行时异常调用者可不处理。
4. 如何选择throws还是try
- 当方法体内处理异常的权限不够时,可以用throws抛出异常由调用者处理
- 异常发生后后面的程序不需要再执行,可以用throws。否则用try
5. final、finally、finalize的区别
1.final
- final是修饰符
- final修饰类时,该类不可以被继承
- final修饰方法时,该方法不可以被重写
- final修饰变量时,该变量是常量,只能被赋值一次
2.finally
- finally一般配合try使用。一般情况下,finally里的代码一定会执行,用于释放资源
3.finalize
- finalize是Object类中的一个方法,用于垃圾回收
6. 异常的注意实现
- 父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常
- 父的方法没有异常抛出,子的重写方法不能有异常抛出,必须自己处理
- 父的方法抛出多个异常,子的重写方法必须比父少或者小
7. 面试题
如下代码所示,如果catch语句中有return,那么return在finally代码之前执行还是之后执行?
public class FinallyDemo2 {
public static void main(String[] args) {
System.out.println(getInt());
}
public static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
} finally {
a = 40;
}
return a;
}
}
返回的a的值为30。
原因是:当程序执行到 a = 30; return a; 时,已经不是return a; 而是return 30;了。但由于后面还有finally语句未执行,所以程序会保存这个返回地址,等处理完finally内的语句后,按原先的返回地址返回。
欢迎转载,表明出处。