异常有两大类:Error和Exception(它们都继承Throwable)
(粉红色为checked异常,浅蓝色为unchecked异常)
Error是JAVA本身的错误,是我们无法处理无法控制无法改变的。
Exception也分为两种:Checked 异常和 Runtime 异常
Checked 异常:其实就是指我们在编写JAVA代码时,不处理这些异常就无法编译。
Runtime 异常:系统会自动抛出此类异常,我们也可以手动去抛出,这种异常属于逻辑异常,是程序员在未知的情况下犯下的错误,是不可控的。
异常处理机制:try / catch / finally
能用正常流程规避的绝不用异常处理,可处理的异常都catch掉,无法处理的 Checked 异常都转变为 Runtime 异常抛出。
try {
//可能发生异常的语句
//如多个可能发生异常的语句,尽量分开写在多个try/catch语句中
//return或throw语句执行后并没有立即返回,而是先执行finally块
//不要忽略捕获到的异常,catch块不要为空,也不要仅打印错误信息
} catch1 (CheckedException e) {
logger.error(e);
//转化并细化,不能抛出更多异常,throw只能抛出实例
throw new RuntimeException(e);
} catch2 (Exception e) {
//异常处理
//此处的异常不能是上一个异常的子类,否则永远运行不到
//return或throw语句执行后并没有立即返回而是先执行finally块
} finally {
//不管抛没抛出异常都需要执行的语句,一般是资源回收
//finally块可以没有
//return或throw语句执行后立即返回,try块和catch块中的return或throw语句均失效
}
使用throws声明抛出异常类
大致过程:当前方法不知道如何处理这种类型的异常,抛出由上一级调用者处理;如果main方法也不知道如何处理,抛出由JVM处理。
public class TestThrows2 extends TestThrows1 {
//要处理test()方法抛出的异常,多个异常类用逗号隔开
public static void main ( String[] args ) throws Exception {
new TestThrows2(). test() ;
}
//重写的方法声明抛出的异常必须是父类方法声明抛出的异常的子类或相同
public void test () throws IOException {
FileInputStream fis = new FileInputStream ("a.txt") ;
}
}
class TestThrows1 {
//一旦使用throws声明抛出异常,就无法使用try/catch来捕获该异常
public void test () throws IOException {
}
}
自定义异常类
自定义的异常类系统无法识别,需要使用throw主动抛出。
public class MyException extends Exception { //自定义异常类都要继承Exception类
MyException () {}
MyException (String msg) {
super (msg) ;
}
/*将原始异常传递给该异常
catch (Exception e) {
throw new MyException(e) ;
}
*/
//如果需要将原始异常传递给该异常,就需要此构造器
MyException (Throwable t) {
super (t) ;
}
}
常见的 Runtime 异常
NullPointerException:空指针异常类
ArrayIndexOutOfBoundsException:数组下标越界异常
ArithmeticExecption:算术异常类
ClassCastException:类型强制转换异常
ArrayStoreException:数据存储异常
NumberFormatException:数字格式异常
常见的 Checked 异常
IOException
SQLException