在设计模式中有一个叫做责任链模式,该模式是将多个对象链接成一条链,客户端的请求沿着这条链传递直到被接收、处理。同样 Java 异常机制也提供了这样一条链:异常链。
我们知道每遇到一个异常信息,我们都需要进行 try…catch,一个还好,如果出现多个异常呢?分类处理肯定会比较麻烦,那就一个 Exception 解决所有的异常吧。这样确实是可以,但是这样处理势必会导致后面的维护难度增加。最好的办法就是将这些异常信息封装,然后捕获我们的封装类即可。
诚然在应用程序中,我们有时候不仅仅只需要封装异常,更需要传递。怎么传递?throws!!但是如果仅仅只用 throws 抛出异常,那么你的封装类,怎么办??
我们有两种方式处理异常,一是 throws 抛出交给上级处理,二是 try…catch 做具体处理。但是这个与上面有什么关联呢?try…catch 的 catch 块我们可以不需要做任何处理,仅仅只用 throw 这个关键字将我们封装异常信息主动抛出来。然后在通过关键字 throws 继续抛出该方法异常。它的上层也可以做这样的处理,以此类推就会产生一条由异常构成的异常链。
通过使用异常链,我们可以提高代码的可理解性、系统的可维护性和友好性。
同理,我们有时候在捕获一个异常后抛出另一个异常信息,并且希望将原始的异常信息也保持起来,这个时候也需要使用异常链。
在异常链的使用中,throw 抛出的是一个新的异常信息,这样势必会导致原有的异常信息丢失,如何保持?在 Throwable 及其子类中的构造器中都可以接受一个 cause 参数,该参数保存了原有的异常信息,通过 getCause ()就可以获取该原始异常信息。
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
class MyException extends Exception {
public MyException(String message) {
super(message);
}
public MyException(String message, Exception e) {
super(message, e);
}
}
public class Test {
public void f() throws MyException {
try {
FileReader reader = new FileReader("G:\\myfile\\struts.txt");
Scanner in = new Scanner(reader);
System.out.println(in.next());
} catch (FileNotFoundException e) {
//e 保存异常信息
throw new MyException("文件没有找到--01", e);
}
}
public void g() throws MyException {
try {
f();
} catch (MyException e) {
//e 保存异常信息
throw new MyException("文件没有找到--02", e);
}
}
public static void main(String[] args) {
Test t = new Test();
try {
t.g();
} catch (MyException e) {
e.printStackTrace();
}
}
}
运行结果:
utils.MyException: 文件没有找到--02
at utils.Test.g(Test.java:35)
at utils.Test.main(Test.java:42)
Caused by: utils.MyException: 文件没有找到--01
at utils.Test.f(Test.java:26)
at utils.Test.g(Test.java:32)
... 1 more
Caused by: java.io.FileNotFoundException: G:\myfile\struts.txt (系统找不到指定的路径。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at utils.Test.f(Test.java:21)
... 2 more
Process finished with exit code 0
来源:oschina
链接:https://my.oschina.net/u/4350591/blog/3225433