Java14对于NullPointerException的新处理方式示例解析
作者:Java后端技术
引言
最近新出的Java14,相信大家有所耳闻,面对NullPointerException,Java14有哪些更好的处理方式呢?
1、传统的NullPointerException
在编码过程中,经常会用到链式的调用方式来写代码,方便清晰,但是一旦出现NullPointerException,就头大了。因为很难知道异常在什么时候发生。举个例子:
String city = employe.getDetailInfo().getAddress().getCity();
在链式调用过程中,如果 employee
,getDetailInfo()
,或者getAddress()
为空,JVM就会抛出NullPointerExeption
,那么导致异常的根本原因是什么?如果不使用调试器,我们很难确认哪个变量为空。而JVM也只会打印导致异常的方法、文件名和行号。
2、增强型 NullPointerException
SAP在2006年为商业JVM实现了增强型的NullPointerException。2019年,被提议作为一个OpenJDK社区的增强。本质上JEP 358通过描述某个变量是"null"来提高JVM生成"NullPointerException"的可读性。通过在方法、文件名和行号旁边描述为null的变量,带来一个详细的NullPointerException消息。通过分析程序的字节码指令来工作,因此能够准确的定位到哪个变量或者表达式为null。
在Java14中,默认是关闭详细的异常消息的。
要启用,需要配置:
-xx:+showCodeDeatilsInExceptionMessages
2.1 详细的异常信息考虑在激活showCodeDeatilsInExceptionMessages
标志的情况下再次运行代码,从附加信息中,可以看到具体的空指针的类,来节省我们调试所用的时间。
JVM有两部分组成详细的异常信息,第一部分表示失败的操作,是引用为null的结果,第二部分标识了null引用的原因
Cannot invoke "String.toLowerCase()" because the return value of "getEmailAddress()" is null
为了生成异常信息,JEP 358重构了将空引用推送到操作数堆栈上的部分源码。
3 技术方面
只有当JVM本身抛出"NullPointerException"时,才会进行详细的消息计划,如果我们在代码中显示抛出异常,则不会执行计算。原因:在这些情况下,很可能已经在异常构造函数中传递了一条有意义的消息。
其次,JEP 358懒汉式的计算消息,这意味着只有当我们打印异常消息的时候,才调用增强的NullPointerException,而不是当异常发生时就调用。因此对于通常的JVM流程不应该有任何性能影响。
最后,详细的异常信息可能包含源代码中的局部变量名。因此我们认为这是一个潜在的安全风险。但是只有运行使用激活的-G标记编译的代码时,才会发生这样的情况。
Employee employee = null; employee.getName();
执行以上代码时,异常信息中会打印本地变量名称:
"com.xxx.xxx.xxx$Employee.getName()"
because "employee" is null
相反,没有额外调试信息的情况下,JVM只提供他在详细信息中所知道的变量
Cannot invoke
"com.xxx.xxx.xxx$Employee.getName()"
because "<locall>" is null
JVM打印编译器分配的变量索引,而不是本地变量名(employee)
通过Java14增强型的NullPointerException,我们可以很快定位出代码问题所在,更快的调试代码,提高效率。
以上就是Java14对于NullPointerException的新处理方式示例解析的详细内容,更多关于Java NullPointerException的资料请关注脚本之家其它相关文章!