Java异常的initCause方法分析

1:作用说明

当我们try住某块代码发生了异常后,希望再catch中throw一个新的异常,但是又不希望丢失引起异常的原始异常则可以使用该方法设置原始异常到我们的新异常中。

2:例子

2.1:定义原始异常

public class OriginException extends Exception {
    
    
    public OriginException() {
    
    }

    public OriginException(String message) {
    
    
        super(message);
    }
}

2.2:定义方法抛出原始异常

public void testA() throws OriginException {
    
    
    throw new OriginException("我是原始异常");
}

2.3:定义新异常

public class NewException extends Exception {
    
    
    public NewException() {
    
    }

    public NewException(String message) {
    
    
        super(message);
    }
}

2.4:定义方法抛出新异常

public void testB() throws NewException {
    
    
    try {
    
    
        this.testA();
    } catch (OriginException e) {
    
    
        NewException newException = new NewException("我是新throw的异常");
        // 设置原始异常
        newException.initCause(e);
        throw newException;
    }
}

2.5:测试代码

public static void main(String[] args) {
    
    
    try {
    
    
        new InitCauseTest().testB();
    } catch (NewException e) {
    
    
        System.out.println("新的异常信息是:" + e.getMessage());
        Throwable cause = e.getCause();
        System.out.println("原始的异常信息是:" + cause.getMessage());
    }
}

运行:

新的异常信息是:我是新throw的异常
原始的异常信息是:我是原始异常

2.6:完整测试代码

public class InitCauseTest {
    
    

    public void testA() throws OriginException {
    
    
        throw new OriginException("我是原始异常");
    }

    public void testB() throws NewException {
    
    
        try {
    
    
            this.testA();
        } catch (OriginException e) {
    
    
            NewException newException = new NewException("我是新throw的异常");
            // 设置原始异常
            newException.initCause(e);
            throw newException;
        }
    }

    public static void main(String[] args) {
    
    
        try {
    
    
            new InitCauseTest().testB();
        } catch (NewException e) {
    
    
            System.out.println("新的异常信息是:" + e.getMessage());
            Throwable cause = e.getCause();
            System.out.println("原始的异常信息是:" + cause.getMessage());
        }
    }
}

3:分析

其中initCause方法源码如下:

java.lang.Throwable#initCause
public synchronized Throwable initCause(Throwable cause) {
    
    
	// <2021-02-26 18:18>
    if (this.cause != this)
        throw new IllegalStateException("Can't overwrite cause with " +
                                        Objects.toString(cause, "a null"), this);
    // 不允许将自己设置为引起异常
    if (cause == this)
        throw new IllegalArgumentException("Self-causation not permitted", this);
    // 设置引起异常的异常
    this.cause = cause;
    return this;
}

可以看到该方法定义在类java.lang.Throwable中,最终执行代码this.cause = cause设置引起异常的原始异常信息。<2021-02-26 18:18>代码,this.cause在异常对象初始化后就是this,即自己,定义private Throwable cause = this;,即默认值就是this,debug验证如下:
在这里插入图片描述
这个时候如果是调用getCause方法会返回null,如下源码:

java.lang.Throwable#getCause
public synchronized Throwable getCause() {
    
    
    return (cause==this ? null : cause);
}

<2021-02-26 18:18>处代码的另一个作用就是只允许设置一次引起异常,我想这应该是基于安全考虑,防止无意或者是有意的篡改,多次调用initCause会发生异常,调用测试如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wang0907/article/details/114143735