廖雪峰Java3异常处理-1错误处理-3抛出异常

1.异常的传播

当某个方法抛出异常时:

  • 如果当前方法没有捕获,异常就被抛到上层调用方法
  • 直到遇到某个try...catch被捕获
  • 使用printStackTrace()打印处方法的调用栈
import java.lang.String;

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);
    }
}

1418970-20190129142158387-1082264931.png

2.抛出异常

  • 创建某个Exception的实例
  • 用throw语句抛出
import java.lang.String;

public class Main {
    public static void main(String[] args) {
        try{
            process1("");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    static void process1(String s){
        throw new IllegalArgumentException();
    }
}

1418970-20190129142714879-1376268164.png

3.转换异常与持有原有异常

3.1转换异常

如果一个方法捕获了某个异常后,又在catch子句中抛出新的异常,就相当与把抛出的异常类型“转换”了。

import java.lang.String;

public class Main {
    public static void main(String[] args) {
        process1("");
    }
    static void process1(String s){
        try{
            process2(s);
        }catch (NullPointerException e){
            throw new IllegalArgumentException();//捕获NullPointerException,抛出IllegalArgumentException
        }
    }
    static void process2(String s){
        throw new NullPointerException();
    }
}

1418970-20190129144033291-213753052.png

3.2转换的异常持有原有异常

上例中存在的问题:新的异常丢失了原始异常信息,只追踪到process1。如何让新的Exception可以持有原始异常信息?
解决方法:将异常传入即可。
throw new IllegalArgumentException(e);

import java.lang.String;

public class Main {
    public static void main(String[] args) {
        process1("");
    }
    static void process1(String s){
        try{
            process2(s);
        }catch (NullPointerException e){
            throw new IllegalArgumentException(e);
        }
    }
    static void process2(String s){
        throw new NullPointerException();
    }
}

1418970-20190129145215827-451969646.png

4.被屏蔽的异常suppressed exception

在抛出异常前,finally语句会保证执行。
如果finally语句抛出异常,则catch语句不再抛出,没有被抛出的异常被称为“被屏蔽”的异常(suppressed exception)

import java.lang.String;

public class Main {
    public static void main(String[] args) {
        try{
            process1("");
        }catch (Exception e){
            System.out.println("catched");
            throw new RuntimeException(e);//“被屏蔽”的异常(suppressed exception)
        }finally {
            System.out.println("finally");
            //throw new NullPointerException();
        }
    }
    static void process1(String s){
        throw new IllegalArgumentException();
    }
}

finally中不抛出异常
1418970-20190129155744723-953473487.png
finally中抛出异常
throw new NullPointerException();去掉注释
1418970-20190129160116698-707026534.png
因此尽量避免在finally中抛出异常

5.如何保存所有的异常信息

  • 使用origin变量保存原始异常
  • 如果存在原始异常,用addSuppressed()添加新异常
  • 如果存在原始异常,或者新异常,最后在finally抛出
import java.lang.String;

public class Main {
    public static void main(String[] args) throws Exception {
        Exception origin = null;
        try{
            process1("");
        }catch (Exception e){
            origin = e;
            System.out.println("catch捕捉到了");
            throw new RuntimeException("可能屏蔽的异常"+e);
        }finally {
            System.out.println("finally");
            try{
                throw new NullPointerException("finally 抛出的异常");
            }catch (Exception e){
                if (origin != null ){
                    origin.addSuppressed(e);
                }else{
                    origin = e;
                }
            }
            if (origin != null){
                throw origin;
            }
        }
    }
    static void process1(String s){
        throw new IllegalArgumentException("process1方法异常了,32");
    }
}

1418970-20190129171516499-1306277936.png

5.2获取所有的异常信息

因为一般不在finally中捕获异常,所以可以直接使用for循环将异常信息打印出来。

import java.lang.String;

public class Main {
    public static void main(String[] args) throws Exception {
        Exception origin = null;
        try{
            process1("");
        }catch (Exception e){
            e.printStackTrace();
            for(Throwable t:e.getSuppressed()){
                t.printStackTrace();
            }
        }finally {
            System.out.println("finally");
        }
    }
    static void process1(String s){
        throw new IllegalArgumentException("process1方法异常了,32");
    }
}

1418970-20190129173524625-1932720916.png

6.总结:

  • printStackTrace()可以打印异常的传播栈,对于调试非常有用
  • 捕获异常并再次抛出新的异常时,应该持有原有异常信息。即新抛出的异常应该包含原始异常。
  • 如果在finally中抛出异常,应该把新抛出的异常添加到原有异常中
  • 用getSuppressed()可以获取所有添加的Suppressed Exception
  • 处理Suppressed Exception要求JDK>= 1.7

转载于:https://www.cnblogs.com/csj2018/p/10306060.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值