java e.getmessage() null,Java 求助! 为什么我拿不到错误信息,e.getMessage()

Java 求助! 为什么我拿不到错误信息,e.getMessage()

Java 求助! 为什么我拿不到错误信息,e.getMessage()

我明明打印了错误信息的啊?

e.getMessage() 是空,为什么?

一声声带着惊讶,带着恐慌,带着质疑,带着无奈的话语,从某个角落里传出。

议论纷纷......

似乎拿不到异常信息是个僵局,只能用玄 学 两个字来 解释。

玄学

初学者若有所思,听到 玄学 两字,思路阔然开朗,频频点头表示 附议。

破局: 不是玄学,不曾了解,无法解释,是因为没有看过这篇文章。

正文

在我们探究为什么异常信息有时候可以打印,有时候又打印不了之前 ,  我们看一下java里  所谓 异常 的家族谱:

08350cc68d75ec00bdb534e2a2754763.png

看过族谱后,我们再回顾我们的代码,当我们使用try .....catch ... 不确定异常类型,我们会选择 抓住 Exception.

可以看到异常族谱图里,  可以看到 Exception底下有三个儿子,

分别是 SQLException ,IOException异常  和 RuntimeException异常;

其中RuntimeException异常 ,运行时异常应该是我们见的最多的了。

空指针,数组越界,类型转换,算数,都是老面孔了。

我们开始上菜。 到底为什么有的异常,e.getMessage()的时候打印为空?

直接先把结论隔这了,

SQLException 和 IOException    这两个家伙的 e.getMessage() 不为空。

RuntimeException 里面的异常,

ArrayIndexOutOfBoundsException,

NullPointerException,

ClassCastException,

ArithmeticException

这些家伙, e.getMessage() 都是  null  。

结合代码分析, 不是我针对空指针,早就看它很不爽,一起解剖它!

public static void main(String[] args) {

try {

List resultList= getResultListTest();

if (resultList.size()>0){

System.out.println("获取到的结果是:"+resultList);

}

} catch (Exception e) {

System.out.println("异常!");

System.out.println(e.getMessage());

}

}

public static List getResultListTest(){

return null;

}

我们故意模拟出空指针异常,重现它的   e.getMessage()  为null :

d52c9ceeb3de851a45c8e12fb0fed76a.png

熟悉的场景, 是玄学!

既然是空,那么我们就看看为什么是空?

这个空的玩意从哪里来!?

一个debug,让空指针的信息无处可逃:

9e5ed8d0674c8354c2b215163fca7f05.png

从debug看到,空指针 NullPointerException 里面 message确实是空的 。不是玄学,来也空,去也空。

而里面的栈信息不是空的,内容丰富了听到,所以如果我们采取的是错误信息栈打印:

e.printStackTrace();

e167df71824afe27c01d5e970fca313e.png

这样看,错误信息就具体了很多,不仅可以指定是什么异常类型,还能看到了报错的行数。

那么很多人就会有想法了, NullPointerException 的 e.getMessage()  为空,但是把e 打印出来应该还是能看到点信息的,不至于 竹篮打水一场 null  ,确实,当你自己非常清楚空指针这个异常的抛出原因时,你可以简单地打印一下 e信息也是可以的:

System.out.println(e.toString());

908a34e41987fa81a381c6634c303e4b.png

看到这,也就是说如果你真想对运行时异常 RuntimeException 里面的相关异常 错误信息打印分析,那么在测试排查阶段,你可以使用 e.printStackTrace();  或者 e.toString();

但是你如果使用的时 e.getMessage()   ,那么到头来就是一场空。

到这里其实已经 简单解释完毕了(别光看着看着,忘记记东西了,下次还以为是玄学就不得行了),就是开头说的:

SQLException 和 IOException    这两个家伙的 e.getMessage() 不为空。

RuntimeException 里面的异常,

ArrayIndexOutOfBoundsException,

NullPointerException,

ClassCastException,

ArithmeticException

这些家伙, e.getMessage() 都是  null  。

利好消息来了! 利好消息来了! 兄弟们上车!

在这里我忍不住要说一下,是不是觉得这个空指针消息,也就是NPE消息,其实是可以没必要空的,完全可以带点可供程序员排查、定位错误的信息。

是的,我相信很多人都是这么想的,所以在JDK 14 和JDK15 的时候, 更好的NPE消息 出现了,JDK 15 Early Access Build#29自动提供了有用的NullPointerException详细信息。

但是现在我们用的是JDK 1.8, 所以先别高兴了,赶紧回到正题。

菜吃到这,有些客官感觉还行,吃饱了;但是有些胃口大开的客观表示,还不够,还想吃。

安排!

看看我找到了什么,没错是源码:

44398df499dfaac83a3d8790b89e2a8e.png

可以看到 NullPointerException 里面有两个构造方法,一个是空的构造方法,一个是可以传msg的构造方法。

当然它的哥哥弟弟姐姐妹妹们也是这样的(我就贴一个类型转换异常,其它runtime异常我就不贴了):

ae4083ab7e2d7a645ac6b93a316a5fc1.png

看到这里,大家可以显然知道,在我们还不是使用JDK15的时候,显然只要是空指针类型,就是相当于抛出来的

NullPointerException 调用的是无参构造方法,也就是跟我们直接new 一个NullPointerException是一个道理,

NullPointerException e = new NullPointerException();

所以这样去 getMessage,为 null 是必然的。

那么我们来简单看看有参的NullPointerException 构造方法使用:

public static void main(String[] args) {

try {

List resultList= getResultListTest(1);

if (resultList.size()>0){

System.out.println("获取到的结果是:"+resultList);

}

} catch (Exception e) {

System.out.println(e.getMessage());

}

}

public static List getResultListTest(int num){

if (num==1){

System.out.println("模拟检测到空,主动抛出异常");

throw new NullPointerException("resultList 为空了啊!");

}

return null;

}

控制台输出:

d5c540e11f61923b8907f94f744fa994.png

没错,这种情况你就可以去通过e.getMessage()获取到自己自定义的异常信息。

这种多用于自定义异常的时候,我们自己去使用异常里带参的构造方法。

什么没听懂怎么使用? 那么可以看看我这篇文章 全局异常捕获(https://blog.csdn.net/qq_35387940/article/details/94176450)

好了,该篇 文章就到此吧。

玄 学?

Java 求助! 为什么我拿不到错误信息,e.getMessage()相关教程

Javaweb——(day01)html与css

Javaweb——(day01)html与css 文章目录 HTML与CSS B/S软件的结构 前端的开发流程 网页的组成部分 HTML简介 创建HTML文件 HTML 标签介绍 常用标签 1.font字体标签 2.特殊字符 3.标题标签 4.超链接 5.列表标签 6.img标签 7.表格标签 8.跨行跨列表格 9.了解ifram

【Java】对象与类

【Java】对象与类 对象和类 类和对象 类的成员 属性 方法 方法重载 方法参数 方法参数的值传递机制 可变个数的形参 构造器 对象 匿名对象 对象的内存解析 类的三大特征 封装 权限修饰符 继承 多态 关键字 this package import 类和对象 属性 属性(成员变量)

Git 记录密码设置

Git 记录密码设置 为什么80%的码农都做不了架构师? 最近日常工作中git代码托管越来越多,git客户端配置何如躲避每次pull/push的时候记录输入密码问题今天做一个总结 对于window 比较简单直接略过了 对于linux 一般可以配置 ssh方式 key配置 1、验证ssh版本

JavaScript定时器

JavaScript定时器 1.往复运动动画 !doctype html html head meta charset=utf-8 titlemotion/title script type=text/javascript window.onload = function(){ var iLeft = 0; var iSpeed = 3; var oDiv = document.getElementById('Div1'); /*clearInterval(

JavaScript封闭函数、常用内置对象、js调试方法

JavaScript封闭函数、常用内置对象、js调试方法 1.封闭函数 封闭函数是JavaScript中匿名函数的另外一种写法,创建一个一开始就执行而不用命名的函数 / 在封闭函数前加’;‘,可以避免js压缩时出错 / ;(function(){ alert('hello world!');})();/*当i大于78时等

JavaScript 循环语句

JavaScript 循环语句 1.for循环 for(......){ .........; } 实例: !doctype html html head meta charset=utf-8 titlecycle/title script type=text/javascript /*var aList01 = ['a','b','c','d'];var aLen = aList01.length;for(var i=0;iaLen;i++){ alert

java的基本数据结构

java的基本数据结构 如图: 数组初始化 int [] a={1,2,3}; int a []={1,2,3}; //推荐使用 基本类型和引用类型存在栈内存中(jvm基础知识) int [] a=new int[16]; new出来的存在堆内存中 知识解析 数组必须初始化,确定内存大小 (强行解释一波:新建一个数组

03-javascript基础----js原型和原型链

03-javascript基础----js原型和原型链 一、原型 原型对象的本质,就是一个普通的Object实例 {} 每个 函数 都有一个 prototype 属性,该属性指向的是原型对象( 显示原型对象 ) 每个 实例对象 身上都有一个 __proto__ 属性,该属性指向的也是原型对象( 隐式

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值