【JAVA】感受下 JDK14 的空指针提示

用户头像
遇见
关注
发布于: 2020 年 04 月 22 日
【JAVA】感受下JDK14的空指针提示

本文旨在带你体验一下JDK14引入的新特性:更有用的空指针异常信息提示,即 JEP 358: Helpful NullPointerExceptions



  1. 下载JDK14

你可以从 OpenJDK 的官方页面下载:JDK 14 General-Availability Release

如果下载速度太慢,还可以去这个 国内镜像站 下载。

  1. 解压,配置环境变量

略。

配置好之后在命令行用 java -version 验证,确保当前用的是 JDK14 版本,示例输出如下:

~$ java -version
openjdk version "14" 2020-03-17
OpenJDK Runtime Environment (build 14+36-1461)
OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)
  1. 编写会抛出空指针异常的代码

Hello.java 内容如下:

public class Hello {
public static void main(String[] args) {
// write your code here
Person p = new Person();
p.firstName = "Wenjian";
p.lastName = null;
String upperLastName = p.lastName.toUpperCase();
String fullName = p.firstName + upperLastName;
System.out.println("full name = " + fullName);
}
static class Person {
public String firstName;
public String lastName;
}
}
  1. 编译并执行

在命令行窗口执行:

javac Hello.java java -XX:+ShowCodeDetailsInExceptionMessages Hello

显示的错误信息如下:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "<local1>.lastName" is null
at Hello.main(Hello.java:8)

从这个信息中不仅能看出异常是在 Hello.java 的第 8 行出现的,还能知道是由于 <local1>.lastName 这个变量为空,所以在执行 String.toUpperCase() 方法时导致的这个异常。

其中:

<local1> 就是指的这个方法中声明的 第1个 local 变量,即 Person p = new Person()

接下来我们把变量 p 赋值为 null,即程序改成如下:

public class Hello {
public static void main(String[] args) {
// write your code here
Person p = null;
p.firstName = "Wenjian";
p.lastName = null;
String upperLastName = p.lastName.toUpperCase();
String fullName = p.firstName + upperLastName;
System.out.println("full name = " + fullName);
}
static class Person {
public String firstName;
public String lastName;
}
}

重新编译并执行之后,错误信息如下:

Exception in thread "main" java.lang.NullPointerException: Cannot assign field "firstName" because "<local1>" is null
at Hello.main(Hello.java:6)

同样的指出了在第 6 行,由于 <local1> 这个变量是 null, 所以在给它的 firstName 字段赋值时抛出了空指针异常,非常清晰。

另外,你可能注意到了,在我们执行程序时,加上了一个参数: -XX:+ShowCodeDetailsInExceptionMessages, 这是因为 JEP358 这个特性虽然在 JDK14 中已经引入,但是没有默认启用,需要在执行时加入这个参数来输出详细的空指针异常信息。

在 JDK15 版本中,这个特性将被默认设置成启用。

The feature can be toggled with the new boolean command-line option -XX:{+|-}ShowCodeDetailsInExceptionMessages. The option will first have default 'false' so that the message is not printed. It is intended to enable code details in exception messages by default in a later release.




20200424,补充:



在执行 javac Hello.java 的时候添加 -g 参数,可以将提示信息的 <local1> 显示为代码中实际的变量名称,对调试更加友好。



如:



javac Hello.java
java -XX:+ShowCodeDetailsInExceptionMessages Hello
Exception in thread "main" java.lang.NullPointerException: Cannot assign field "firstName" because "p" is null
at Hello.main(Hello.java:6)



原理是:如果编译的时候加入了 -g 参数,javac 会把变量名字写入到 .class 文件中去。



发布于: 2020 年 04 月 22 日 阅读数: 99
用户头像

遇见

关注

A good code is like a story not a puzzle 2019.08.08 加入

人生是 B 和 D 之间的 C 选择。

评论

发布
暂无评论
【JAVA】感受下JDK14的空指针提示