重新抛出异常与异常链

重新抛出异常

如果我们直接重新抛出异常,那么当我们后续捕获此异常时并不会产生重新抛出地的信息。但是当我们需要重新抛出一个异常时我们显然希望能获得重新抛出点的信息,这时我们需要使用fillInStackTrace()方法,它通过把当前异常调用栈信息填入原来的异常对象而返回一个Throwable,所以我们需要将它强制转型为Exception再将其抛出。

import java.io.*;
class ExceptionTest{
    public static void fun1() throws IOException{
        throw new IOException("fun1()");
    }
    public static void fun2() throws IOException{
        throw new IOException("fun2()");
    }
}

public class FuUse{

    /*
    * invoke1()使用fillInstackTrace()方法抛出
    * */
    private static void invoke1() throws Exception{
        try {
            ExceptionTest.fun1();
        }catch (IOException e){

            /*
            * 将异常调用栈轨迹信息重定向到System.out中
            * 默认是System.err。
            * */
            e.printStackTrace(System.out);

            /*
            * e.fillInStackTrace()返回的是Throwable类型
            * */
                throw (Exception)e.fillInStackTrace();
        }
    }

    /*
    * invoke2()直接重新抛出异常
    * */
    private static void invoke2() throws Exception{
        try {
            ExceptionTest.fun1();
        }catch (IOException e){
            e.printStackTrace(System.out);
            throw e;
        }
    }

    public static void main(String[] args){

        try {
            invoke1();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        System.out.println("----------------------------------");
        try {
            invoke2();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }
}
/*
*output:
java.io.IOException: fun1()
	at ExceptionTest.fun1(FuUse.java:4)
	at FuUse.invoke1(FuUse.java:18)
	at FuUse.main(FuUse.java:49)
java.io.IOException: fun1()
	at FuUse.invoke1(FuUse.java:30)
	at FuUse.main(FuUse.java:49)
----------------------------------
java.io.IOException: fun1()
	at ExceptionTest.fun1(FuUse.java:4)
	at FuUse.invoke2(FuUse.java:39)
	at FuUse.main(FuUse.java:55)
java.io.IOException: fun1()
	at ExceptionTest.fun1(FuUse.java:4)
	at FuUse.invoke2(FuUse.java:39)
	at FuUse.main(FuUse.java:55)
* */

可以看到invoke2()中两个不同的抛出点都输出了通用的栈轨迹信息,而invoke1()中产生了重新抛出点的信息。

 

异常链

常常会在捕获一个异常后抛出另一个异常,并且希望把原始的异常信息保存下来,这被称为异常链。

这种情况可以举一个例子。比如针对用户来说,我们希望提供给他们的错误信息将细节隐藏,并使错误表达的简单明了。这时我们建立需要的自定义异常,在捕获到一些用户不需要知道的异常时,我们将用户易懂的自定义异常抛出(这种行为往往用来转换异常)。但是作为开发者我们需要知道异常发生的细节,现在就需要使用异常链的功能来实现。

import java.io.*;
/*
* 自定义异常WrongOperationException
* */
class WrongOperationException extends Exception{}

class ExceptionTest{
    public static void fun() throws IOException{
        throw new IOException();
    }
}
public class FuUse{
    
    private static void invoke1() throws WrongOperationException{
        try {
            ExceptionTest.fun();
        }catch (IOException e){
            
            /*
            * 将原异常对象设置为新异常对象的“原由”
            * initCase();
            * */
            
            WrongOperationException wrongOperation = new WrongOperationException();
            wrongOperation.initCause(e);
            throw wrongOperation;
        }
    }

    public static void main(String[] args){
        try {
            invoke1();
        } catch (WrongOperationException e) {
            e.printStackTrace(System.out);
        }

    }
}
/*
*output:
WrongOperationException
	at FuUse.invoke1(FuUse.java:17)
	at FuUse.main(FuUse.java:26)
Caused by: java.io.IOException
	at ExceptionTest.fun(FuUse.java:5)
	at FuUse.invoke1(FuUse.java:15)
	... 1 more
* */

当我们在捕获受查异常时,有时我们想在捕获到这个异常时不做处理直接终止程序。这时我们可以利用异常链的原理将受查异常当成非受查异常的原由。这就在形式上将受查异常转换成了非受查异常。

import java.io.*;
class ExceptionTest{
    public static void fun() throws IOException{
        throw new IOException();
    }
}
public class FuUse{

    private static void invoke1(){
        try {
            ExceptionTest.fun();
        }catch (IOException e){
            /*
            * 将原异常对象设置为非受查异常对象的“原由”
            * */
            RuntimeException runtimeException = new RuntimeException();
            runtimeException.initCause(e);
            throw runtimeException;
        }
    }
    public static void main(String[] args){
        invoke1();
    }
}
/*
*output:
Exception in thread "main" java.lang.RuntimeException
	at FuUse.invoke1(FuUse.java:16)
	at FuUse.main(FuUse.java:24)
Caused by: java.io.IOException
	at ExceptionTest.fun(FuUse.java:4)
	at FuUse.invoke1(FuUse.java:11)
	... 1 more
* */

 

转载于:https://www.cnblogs.com/old-driver-lgq/p/10806271.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值