异常的传播
当某个方法抛出异常的时:
- 如果当前方法没有捕获异常,异常就会抛到上层调用方法直到遇到某个 try...catch被捕获
- printStackTrace()可以打印出方法的调用栈,就可以知道哪一行出了问题
package wensong.com;
public class CatchException {
public static void main(String[] args) {
try{
process1();
}catch(Exception e){
e.printStackTrace();
}
}
static void process1(){
process2();
}
static void process2(){
Integer.parseInt(null);
}
}
运行结果如下,我们就知道6,12,16行出了问题:
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
at wensong.com.CatchException.process2(CatchException.java:16)
at wensong.com.CatchException.process1(CatchException.java:12)
at wensong.com.CatchException.main(CatchException.java:6)
Process finished with exit code 0
主动抛出异常
因为异常也是类,所以我们要(new)创建某个异常的实例,然后用throw语句抛出:
package wensong.com;
public class ThrowException {
public static void main(String[] args) {
try{
process1("");
}catch(Exception e){
e.printStackTrace();
}
}
static void process1(String s){
throw new IllegalArgumentException();
}
}
运行结果:
java.lang.IllegalArgumentException
at wensong.com.ThrowException.process1(ThrowException.java:12)
at wensong.com.ThrowException.main(ThrowException.java:6)
Process finished with exit code 0
异常转换
如果一个方法捕获了某个异常后,又在catch语句中抛出新的异常,就相当于把抛出的异常‘’转换‘’了;但是这样原有的异常信息不就丢失了吗?我们可以在新的异常的构造方法中将原来的异常作为参数,就可以使新的异常保持原有异常的信息了:
package wensong.com;
public class TranslateException {
public static void main(String[] args) {
process1("");
}
static void process1(String s){
try{
process2();
}catch(NullPointerException e){
throw new IllegalArgumentException(e);
}
}
static void process2(){
throw new NullPointerException();
}
}
在异常抛出之前:finally语句会保证先执行,然后再抛出catch中的异常,如果finally中也抛出异常,则最后抛出的异常是finally中的,catch中的不会再抛出,因为被覆盖掉了,Java中只能抛出一个异常。没有抛出的异常被称为“被屏蔽”的异常(suppressed exception),但是一般不会在finally中抛出异常。
package wensong.com;
public class FinallyException {
public static void main(String[] args) {
try{
process1("");
}catch(Exception e){
System.out.println("catched:");
throw new RuntimeException(e);
}finally{
System.out.println("finally");
throw new NullPointerException();
}
}
static void process1(String s){
throw new IllegalArgumentException();
}
}
执行结果很明显:
catched:
finally
Exception in thread "main" java.lang.NullPointerException
at wensong.com.FinallyException.main(FinallyException.java:12)
如何获取所有异常:
1,(不建议)用origin变量保存原始异常,如果存在原始异常,用addSuppressed()添加新异常,如果存在原始异常,或者新异常,最后在finally抛出:
Exception origin = null;
try{
process1("");
}catch(Exception 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;
}
}
2,用getSuppressed()获取所有SuppressedException:
try{
somethingWrong("");
}catch(Exception e){
e.printStackTrace();
for(Throwable t : e.getSuppressed()){
t.printStackTrace();
}