Java中多层异常包裹时候获取最底层的最真实异常-分析Java异常栈

Posted javartisan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中多层异常包裹时候获取最底层的最真实异常-分析Java异常栈相关的知识,希望对你有一定的参考价值。

示例代码:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

class AudienceLimitExcption extends Exception 
    public AudienceLimitExcption(String message, Throwable cause) 
        super(message, cause);
    


class Task implements Callable 

    @Override
    public Object call() throws Exception 
        try 
            System.out.println(1 / 0);
         catch (Exception e) 

            throw new AudienceLimitExcption("limit error", e);
        

        return 1;
    

 

代码异常1:


public class Main 

    public static void main(String[] args) 
        Object r = null;
        ExecutorService es = Executors.newFixedThreadPool(4);
        try 
            Future f = es.submit(new Task());
            r = f.get();
            System.out.println();
         catch (Throwable e) 
            System.out.println(e.getClass());
        
    

输出结果:class java.util.concurrent.ExecutionException  不是最真实的底层抛出去的异常。

分析异常栈:

会发现当cause==当前异常时候就是最真实异常,于是代码如下:


public class Main 

    public static void main(String[] args) 
        Object r = null;
        ExecutorService es = Executors.newFixedThreadPool(4);
        try 
            Future f = es.submit(new Task());
            r = f.get();
            System.out.println();
         catch (Throwable e) 
            while (e != null) 
                Throwable cause = e.getCause();
                if (e.equals(cause)) 
                    System.out.println(e);
                
                e = cause;
            
        
    

运行发现没有输出,debug发现当e为真实异常时候,e.getCause方法返回值为null。因此if分支无法为true,所以没有输出。与上图异常栈分析结论相悖,只能查看一下getCause方法实现:

    public synchronized Throwable getCause() 
        return (cause==this ? null : cause);
    

JDK实现时候,当cause等于当前异常e时候直接返回null,因此正确方案如下:


public class Main 

    public static void main(String[] args) 
        Object r = null;
        ExecutorService es = Executors.newFixedThreadPool(4);
        try 
            Future f = es.submit(new Task());
            r = f.get();
            System.out.println();
         catch (Throwable e) 
            while (e != null) 
                Throwable cause = e.getCause();
                if (cause == null) 
                    System.out.println(e.getClass());
                
                e = cause;
            
        
    

输出结果也就是1/0最真实的异常类型:class java.lang.ArithmeticException

 

 

 

以上是关于Java中多层异常包裹时候获取最底层的最真实异常-分析Java异常栈的主要内容,如果未能解决你的问题,请参考以下文章

InvalidPathException异常问题

Bug解决:获取JDBC连接失败;嵌套异常是java.sql.SQLException:无法从底层数据库获取连接

c++异常处理

Java异常链

Nginx多层反向代理透传客户端真实IP

从第三方 WCF 获取底层异常 - SOAP 异常