public class Exception extends Throwable {
static final long serialVersionUID = -3387516993124229948L;
public Exception() {
super();
}
public Exception(String message) {
super(message);
}
public Exception(String message, Throwable cause) {
super(message, cause);
}
public Exception(Throwable cause) {
super(cause);
}
}
1.1.2. throw
将异常对象的引用传递给throw,从效果上看,它就像从方法中“返回”一样,可以将异常处理当做一种不同的返回机制。不同的是return返回到方法调用点,throw返回到异常处理程序。
1 |
2
3
4
private String throwException(){
//return “Test”;
throw new RuntimeException(“Test Exception”);
}
1.1.3. try
“监控区域”是一段可能产生异常的代码,并且后面跟着处理这些异常的代码。可以简单的理解为try块就是监控区域。
如果在方法内部抛出异常(或调用其他方法出现异常),这个方法将在抛出异常的点结束,如果不希望方法结束,那么需要在方法内设置一个特殊的块来捕获异常。
1 |
2
3
4
5
6
7
8
9
private String tryException(){
try {
// 监控区域
return throwException();
}catch (Exception e){
// 异常处理区域
}
return “”;
}
1.1.4. catch
抛出的异常必须在某处得到处理,这个点就是异常处理程序。针对每个要捕获的异常,准备相应的处理程序。异常处理程序紧跟着try块,以关键字catch表示。
每个catch子句,看起来就像是接收一个且只接收一个特殊异常类型的方法。当异常发生后,异常处理机制会搜寻参数与异常类型匹配的第一个异常处理器,然后进入catch子句执行,此时认为异常得到了处理。一旦catch子句结束,则处理程序的查找过程结束。
在查找异常处理器时,并不要求抛出的异常与异常处理器所声明的异常完全匹配。派生类的对象也可以匹配基类的处理器。
1 |
2
3
4
5
6
7
8
9
10
11
12
private String tryException(){
try {
// 监控区域
return throwException();
}catch (RuntimeException e){
// 处理 RuntimeException 情况
}
catch (Exception e){
// 处理 Exception 情况
}
return “”;
}
顺序,异常处理机制会搜索第一个匹配的异常处理器,因此catch语句的顺序至关重要,通常将具体类型前置,通用类型后置。
1.1.5. finally
对于一些代码,可能会希望无论try块中是否抛出异常,他们都会执行。为了达到效果,可以在异常处理后面加上finally子句。
对于没有垃圾回收和析构函数自动调用机制的语言来说,finally非常重要。它是程序员能够保证在任何情况下,内存总能得到释放。但在Java中存在垃圾回收机制,内存释放不再是个问题。当要把除内存外的资源恢复到他们的初始化状态时,就需要使用finally子句。常见的资源包括:网络链接、文件句柄、显示锁等。
1 |
2
3
4
5
6
7
8
9
10
11
12
13
14
private String tryException(){
try {
// 监控区域
return throwException();
}catch (RuntimeException e){
// 处理 RuntimeException 情况
}
catch (Exception e){
// 处理 Exception 情况
}finally {
// 对 网络链接、文件句柄、锁等资源进行处理
}
return “”;
}
1.2 方法异常说明
Java鼓励将方法可能会抛出的异常告知使用该方法的客户端。这种做法,使得调用者能知道在代码中可以获取所有的异常。
异常说明在方法声明中使用附加的关键字throws,后面接一个所有潜在异常类型列表,所以方法签名变成:
1 |
2
3
4
5
// 方法异常说明
private List<String> readFromFile(String filePath) throws IOException {
Path path = Paths.get(filePath);