Analysis of the initCause method of Java exception

1: Function description

When we try to live in a certain block of code after an exception occurs, we hope to throw a new exception in the catch, but we don't want to lose the original exception that caused the exception, we can use this method to set the original exception to our new exception.

2: Example

2.1: Define the original exception

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

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

2.2: The definition method throws the original exception

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

2.3: Define a new exception

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

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

2.4: Define the method to throw a new exception

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

2.5: Test code

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

run:

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

2.6: Complete test code

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: Analysis

The source code of the initCause method is as follows:

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

You can see that the method is defined in the class java.lang.Throwable, and the final execution code this.cause = causesets the original exception information that caused the exception. <2021-02-26 18:18>The code, this.causeafter the exception object is initialized, is this, that is, the definition private Throwable cause = this;, that is, the default value is this, debug verification is as follows: at
Insert picture description here
this time, if the getCausemethod is called, it will return null. The source code is as follows:

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

<2021-02-26 18:18>Another function of the code is to allow the setting to cause an exception only once. I think this should be based on security considerations to prevent accidental or deliberate tampering. initCauseExceptions will occur after multiple calls . The call test is as follows:
Insert picture description here

Guess you like

Origin blog.csdn.net/wang0907/article/details/114143735