JAVA中的异常类都继承自Throwable类,也就是说,这是异常类的根。Throwable类扩展了两个类Error类和Exception类,Exception类又扩展了一个RuntimeException类。如下图:
Error:称为错误,由Java虚拟机生成并抛出,这类错误一般是运行时系统内部的错误,无法被处理。
Exception:所有异常类的父类,其子类对应了各种各样可能出现的异常事件,一般需要用户显式地声明或捕获。如文件类异常:FileNotFoundException,IOExecption。
RuntimeException:一种特殊的异常类,继承自Exception类。如除数为0、数组下标越界等。这类异常产生比较频繁,用户一般不对其做捕获处理,否则对程序的可读性和运行效率影响很大,而是由系统自动检测并将它们交给默认的异常处理程序进行处理。如ArithmeticException,ArrayIndexOutOfBoundException。
一般来说,出现RuntimeException异常表示的是代码不合理而出现的问题。
未检查异常:Error错误和RuntimeException类的异常;
已检查异常:Exception类的异常但不包括RuntimeException类。
因此,在自定义异常类型时,大多数都直接继承Exception类,偶尔可能继承RuntimeException类,更偶尔的可能会继承这些类的某些子类。
try-catch-finally结构和处理流程使用try-catch结构捕捉异常,并设置捕捉到后的处理方式。还可以加上finally结构,这是可选结构,但却表示try结构中必须会被执行的部分。
以下是try-catch-finally结构和处理过程的分析。
try { // 待捕捉测试的代码1 // 待捕捉测试的代码2 (假设此为异常代码,将抛出名为异常名2的异常) // 待捕捉测试的代码3 } catch (异常名1 对象名e) { // 捕捉到异常名1的异常后,该做的处理代码4 } catch (异常名2 对象名e) { // 捕捉到异常名2的异常后,该做的处理代码5 } ... { //... } finally { //一定会执行的代码6 } //try结构外的代码7前提假设,在各代码中没有return子句。执行过程为:首先代码1正常执行,到代码2处抛出异常名2的异常,通过异常名匹配,将选择第二个catch结构,于是将异常2封装到对象名e中,并执行代码5处理异常。catch部分处理完后,还有最后处理段finally,于是执行代码6。出了finally后,还将执行代码7。
注意,当代码2出现异常后,代码3不会执行。而finally则是无论是否真的捕捉到了异常、是否在catch段有return都会执行的代码段。换句话说,finally段的代码除了内部错误或外界影响都一定会执行。就像下面的例子中,即使catch使用了return,但finally还是会执行,只不过这个catch终止了try结构外的代码。
例如,除数为0时会抛出ArithmeticException异常。try-catch捕捉它:
public class TEx { public static void main(String[] args) { try { System.out.println("[start]"); System.out.println(2/0); System.out.println("[end]"); } catch (ArithmeticException e) { System.out.println("[Catching]: " + e); return; } finally { System.out.println("[Finally]"); } System.out.println("[out of try-catch]"); } }在finally段中还可以继续try-catch-finally,防止该段落的代码再次抛出异常。
public class TEx { public static void main(String[] args) { try { System.out.println("[start]"); System.out.println(2/0); System.out.println("[end]"); } catch (ArithmeticException e) { System.out.println("[Catching]: " + e); return; } finally { try { System.out.println("[Finally-try-start]"); System.out.println(3/0); } catch (ArithmeticException e) { System.out.println("[Finally-Catching]: " + e); } } System.out.println("[out of try-catch]"); } } 输出异常信息java中的异常都会封装到对象中。异常对象中有几个方法:
printStackTrace():输出最详细的信息,包括抛出异常的行号,异常信息以及异常原因。
getMessage():输出异常信息。
getCause():输出异常原因。
异常抛出过程和throw、throws关键字