1.异常的传播
当某个方法抛出异常时:
- 如果当前方法没有捕获,异常就被抛到上层调用方法
- 直到遇到某个try ...catch 被捕获
- printStackTrace()可以打印出方法的调用栈
- printStackTrace()对于调试错误非常有用
public class Main {
public static void main(String[] args){
try {
process1();
} catch (Exception e) {
e.printStackTrace();
}
}
static void process1() {
process2();
}
static void process2() {
Integer.parseInt(null);
}
}
2.抛出异常
之所以可以捕获异常,是因为某些方法可以抛出异常,如何抛出异常:
- 创建某个Exception的实例
- 用throw语句抛出
public class Main {
public static void main(String[] args){
try {
process1("");
} catch (Exception e) {
e.printStackTrace();
}
}
static void process1(String s) {
throw new IllegalArgumentException();
}
}
在抛出异常之前:
- finally语句会保证执行
- 如果finally语句抛出异常,则catch语句不再抛出
- 没有被抛出的异常称为“被屏蔽”的异常(suppressed exception)
suppressed exception
如何保存所有的异常信息?
- 用origin变量保存原始异常
- 如果存在原始异常,用addSuppressed()添加新异常
- 如果存在原始异常,或者新异常,最后在finally抛出
Exception ogrigin = null;
try{
process1("");
} catch (Excetion e) {
origin = e;
throw new RuntimeException(e);
} finally {
try{
throw new NullPointerException();
} catch (Exception e) {
if (origin != null) {
origin.addSuppressed(e);
} else {
origin = e;
}
}
if (origin != null) {
throw origin;
}
}
如何获取所有的异常信息?
- 用getSuppressed()获取所有Suppressed Exception
try {
somethingWrong("");
} catch (Exception e) {
e.printStackTrace();
for (Throwable t : e.getSuppressed()) {
t.printStackTrace();
}
}
3.转换异常
如果一个方法捕获了某个异常后,又在catch子句中抛出新的异常,就相当于把抛出的异常类型“转换”了:
- 新的异常丢失了原始异常信息
- 新的Exception可以持有原始异常信息
public class Main {
public static void main(String[] args){
process1("");
}
static void process1 (String s){
try {
process2();
} catch (NullPointerException e) {
throw new IllegalArgumentException(e);
}
}
static void process2(String s) {
throw new NullPointerException();
}
}
public class Main {
public static void main(String[] args){
process1();
}
static void process1 (){
try {
process2();
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("END");
}
}
static void process2() {
process3();
}
static void process3() {
try {
Integer.parseInt(null);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(e);
} finally {
System.out.println("finally...");
//finally语句中若抛出异常...
throw new NullPointerException();
}
}
}
4.总结
- printStackTrace()可以打印异常的传播栈,对于调试非常有用
- 捕获异常并再次抛出新的异常时,应该持有原始异常信息
- 如果在finally中抛出异常,应该把新抛出的异常添加到原有异常中
- 用getSuppressed()可以获取所有添加的Suppressed Exception
- 处理Suppressed Exception要求JDK >= 1.7