Throwable是Java程序中所有异常对象的根基类,而Throwable是从Object类直接继承来的,
Throwable可分为error(错误)和 Exception(异常)。error表示的是JDK出了问题,与写的代码无关;而Exception是指程序本身出了问题,可以通过修改代码进行修复。
其中Exception又包含两大子类:RuntimeException(运行时异常)和Checked Exceptions(检查时异常)
我在网上看到一张图片,在这里分享一下,有助于理解Throwable:
通常异常会导致异常一下的语句无法再执行,例如:
public class Test{
public static void main(String[] args) {
int age = 20;
System.out.println(age);//可以执行
System.out.println(1/0);//异常
System.out.println(age);//不可以执行
}
}
输出结果:
20
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.jd.test1.Test1.main(Test1.java:9)
上面的这个异常就属于算数异常(ArithmeticException),而算数异常就属于RuntimeException中的一种。那我们如何区分RuntimeException(运行时异常)和Checked Exceptions(检查时异常)呢?
有两种方法:
- 一种是通过父类区分,如果该异常类型直接或间接的继承了RuntimeException,则该异常就为运行时异常,否则就为检查时异常;
- 另一种是通过是否需要进行显式处理来区分:不需要进行显式处理的就为运行时异常,必须进行显式处理的就为检查时异常,让我们来举个例子:
public class Test{
public static void main(String[] args) {
System.out.println(1/0);//无需显式处理,因此为运行时异常
//ArithmeticException,继承了RuntimeException,因此为运行时异常
try {
Class.forName("java.lang.Object");//需要显式处理,因此为检查时异常
} catch (ClassNotFoundException e) {//没有直接或间接继承RuntimeException,因此为检查时异常
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
异常通常可以用try-catch-finally来进行处理,例如上面的try-catch代码,其中try用于检查语句块是否有异常,若有异常则进入catch语句块,然后catch判定该异常类型是否与括号里的异常类型相同,若相同,则将异常类型赋值给变量e; 而且可以添加多个catch语句块,每个语句块里都可以写一种异常类型,执行时按照就近原则进行(距离try语句块的远近),但要注意的是要按照异常类型范围从小到大依次往下添加; 而finally语句块可以添加到catch语句块后面,无论try里的语句是否有异常都会执行。
让我们来举个例子深入理解一下:
public class Test3 {
public static void main(String[] args) {
try {
String str = null;
System.out.println(str.length());//因为此处异常,所以下一行语句不执行,直接跳到catch语句块里
Class.forName("fafsdf");
}catch(ArithmeticException e){//算数异常
System.out.println(e);
}catch(NullPointerException e){//空指针异常,因为上面的异常为空指针异常,所以跳到此catch语句块里
System.out.println(e);
}catch(RuntimeException e){//执行时异常
System.out.println(e);
}catch(Exception e){//异常
System.out.println(e);
}finally {
System.out.println("管你怎样,我就要执行");
}
}
}
输出结果:
java.lang.NullPointerException
管你怎样,我就要执行