摘要:
- 记录看书过程中,看到的知识点,简单梳理,以供反复查看
基类
Exception 继承自 Throwable,是所有异常类(~Exception)的父类。 Exception 有四个构造函数,一般所有的异常类都有两个标准的构造函数:
- 默认构造函数(无参数)
- 以一个 string 为参数的构造函数。 这个字符串可以通过调用 getMessage() 方法获取。
创建异常类
我们创建的异常类需要继承 Exception 类或者其子类, 或者继承自 Throwable 类。
一般创建异常类的话,要起好名字,做到“望文生义”:
class SimpleException extends Exception {}
这样一来会自动的为我们的异常类添加一个默认的构造函数。如果需要的话, 也可以自己在添加一个以 string 为参数的构造函数。
class SimpleException exends Exception {
public SimpleException() {}
public SimpleException(String s) {
super(msg);
}
}
Exception 类中方法简介
-
getMessage() | getLocalizedMessage() 返回关于此类的详细信息。
- getMessage() 返回的就是异常构造时的那个 message,如果没有此 message,则返回的是 null
- getLocalizedMessage() 方法就是直接调用了 getMessage(),返回的值相同。但是这个方法适用于 Exception 的子类重写的,如果重写了,则会返回不同值。
-
void printStackTrace() 在标准输出错误流中打印此报错方法的调用栈,可以看到我们是如何从主函数一步一步的走到这个方法的异常代码部分。
-
StackTraceElement[] getStackTrace() 获取此异常方法的调用栈帧,组成一个数组返回。
捕获异常
使用 try...catch... 语句捕获异常,如下:
try {
// 运行的代码
} catch(ExceptionType1 e1) {
// 关于处理此类型异常的代码
} catch(ExceptionType2 e2) {
// 关于处理此类型异常的代码
} finally {
// 一定会执行的代码
}
- try 语句中的代码是我们想要执行的逻辑代码,但是在执行的过程中可能会出错。一旦出错,出错行之后的代码不再执行,进入 catch 语句。
- catch 语句是用来捕获异常并处理,就像函数定义一样,但是它只有一个参数。
- finally 是一定会执行的代码, 不论 try 中调用 return, break, continue 都会执行这部分的代码(try 中,如果 return, break, continue 之后还有程序,编译器报错)。
- 如果 try 语句中有返回语句,而返回的值在 finally 中被修改了。 如果运行的过程中没报错,会返回 try 中的返回值, finally 对最后的返回值没有影响。
注意:
- catch 语句会按照顺序匹配查找
- 一旦某个 catch 语句匹配上了,就进入此 catch,执行完后,下面的所有 catch 语句都不会再执行了。
- catch 语句中,如果一个父类异常排在子类异常的前面,也会报错,因为这个子类异常不可抵达,相当于无用。
- 如果在 try 主体中确定不会抛出某一类型的异常,此异常就不能出现在 catch 语句中,否则会编译报错。
重新抛出异常
在使用 catch 语句捕获异常后,因为某些原因,我们需要将这个异常重新抛出。重新抛出异常后,就不会被此 try...catch...语句剩余的 catch 语句捕获,而是被其上一层的异常处理语句捕获(调用此函数的异常处理机制)。
简单重抛异常
// some code
try {
// some code
} catch(Exception e) {
// some code
throw e;
}
// some code
这样重新抛出的异常,被其他方法捕获后,使用 printStackTrace() 打印出的调用栈与原异常相同。即重新抛出不会改变异常。
调用 fillInStackTrace() 改变函数调用栈
// some code
try {
// some code
} catch(Exception e) {
// some code
throw (Exception)e.filInlStackTrace();
}
// some code
fillInStackTrace() 调用的地方就是新的异常发生的地方。
也可以重新抛出改变类型的异常
这样的话,相当于抛出了新的异常,关于原始异常的一切都会消失,貌似没有出现此异常一般。
异常声明 exception specification
在 java 中,当我们定义一个方法时,如果这个方法内部使用 throw 抛出异常,则此方法必须添加异常声明,告诉其他人,这个方法在调用的过程中可能会抛出哪些异常。例如:
// 此方法会抛出三个异常
public void f() throws TooBigException, ToSmallException, DivZeroException {
// 方法实现
}
// 此方法不会抛出异常
public void f() {
// 方法实现
}
注意:
- 继承自 RunTimeException 的异常可以不必出现在异常声明中,这些异常随时随地可以被抛出。
- 当你的方法中抛出异常时,如果你没有在方法中处理此异常,则必须在方法头部进行异常声明,否则会编译器报错。
- 你可以在异常声明中包含此方法没有扔出的异常。例如,可以声明此方法抛出了 C 异常,但其实在方法的实现过程中并没有抛出异常。
网友评论