【打印空指针异常信息getMessage为null】


版本:JDK 1.8

某次解析数据进业务表时数据异常,查询接口表想查看错误消息结果发现字段均为空,由于接口表其余字段均回写正常,推测应该是捕获异常信息来返回错误消息字段这部分出了问题。

写了测试方法如下: 

    @Test
    public void returnErrorMessage(){
        try {
            User user = null;
            List userList = new ArrayList<>();
            // 模拟数组越界
            userList.get(0);
/*            if(user.getId()!= 0){
                System.out.println("异常测试");
            }*/
        } catch (Exception e) {
            System.out.println("测试直接getMessage是否能打印异常: "+e.getMessage());
            System.out.println("==分割线==");
            StringWriter stringWriter= new StringWriter();
            PrintWriter writer= new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer= stringWriter.getBuffer();
            // 截取前200长度的报错信息
            String error = buffer.toString().substring(0, 200);
            System.out.println("测试Buffer能否打印异常 "+error);
            // printStackTrace()是指将异常本身和异常信息输出到标准的错误流
            System.out.println("e.printStackTrace: ");
            e.printStackTrace();
        }
    }

控制台输出:

测试直接getMessage是否能打印异常: Index: 0, Size: 0
==分割线==
测试Buffer能否打印异常 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.get(ArrayList.java:433)
    at com.wang.dao.UserDaoTest.returnErro
e.printStackTrace: 
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.get(ArrayList.java:433)
    at com.wang.dao.UserDaoTest.returnErrorMessage(UserDaoTest.java:1625)
   下略.............

Process finished with exit code 0

如果 换成 空指针测试:

        try {
            User user = null;
            List userList = new ArrayList<>();
 // userList.get(0);
            if(user.getId()!= 0){
                System.out.println("异常测试");
            }
        } catch (Exception e) {同上}

控制台输出:

测试直接getMessage是否能打印异常: null
==分割线==
测试Buffer能否打印异常 java.lang.NullPointerException
    at com.wang.dao.UserDaoTest.returnErrorMessage(UserDaoTest.java:1627)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAcc
e.printStackTrace: 
java.lang.NullPointerException
    at com.wang.dao.UserDaoTest.returnErrorMessage(UserDaoTest.java:1627)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

发现getMessage获得返回信息为null,debug模式下可以看到:

空指针捕获:

 数组越界捕获:

可以看到数组越界的异常时getMessage有返回值

点击getMessage,在源码里发现Throwable 方法有多个,但是通过断点发现它每个方法都执行了,在这里detailMessage已经是空了

于是继续追溯,我们在空指针源码里打了断点:

 我感觉是因为这个原因,它走了无detailMessage的构造方法,所以最后返回为null

 小结:

  总之是因为detailMessage为null且返回导致结果为空,不过栈打印是有内容的,所以我们可以先打印输出流 e.printStackTrace(writer);

用getBuffer 获取转为字符串 存储: StringBuffer buffer= stringWriter.getBuffer();

// 截取前200长度的报错信息 String error = buffer.toString().substring(0, 200);

这样就可以获取具体的错误信息了

具体代码见最上