在Java 17及之前的版本中,关于空指针异常(NullPointerException)的友好提示主要依赖于开发者在编写代码时的注意和检查,而不是Java语言本身直接提供的特性。然而,从Java 14开始,Java平台引入了一些改进,旨在使空指针异常(NPE)的调试变得更加容易,这可以视为一种“友好提示”的间接实现。

Java 14及之后的改进

在Java 14中,引入了JEP 358(Helpful NullPointerExceptions),这是一个旨在改进空指针异常诊断信息的提案。通过增加JVM启动参数-XX:+ShowCodeDetailsInExceptionMessages,当程序抛出空指针异常时,异常信息中将包含更详细的代码位置信息,从而帮助开发者更快地定位问题。

这一特性虽然不直接改变空指针异常的处理方式,但显著提高了异常信息的可读性和有用性,使得开发者能够更容易地理解为什么以及在哪里发生了空指针异常。

示例

假设有一个简单的Java程序,它试图调用一个null对象的方法:

package com.morris.java17;

/**
 * 演示Helpful NullPointerExceptions空指针友好提示特性
 */
public class NullPointerDemo {

    public static void main(String[] args) {
        A a = null;
        a.getB().someMethod();
    }

}

class A {
    private B b;

    public B getB() {
        return b;
    }
}

class B {
    public void someMethod() {
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

在Java14以下的版本中异常输出如下:

Exception in thread "main" java.lang.NullPointerException
	at com.morris.java17.NullPointerDemo.main(NullPointerDemo.java:10)
  • 1.
  • 2.

输出将显示NullPointerException发生的行号,但不知道哪个方法调用时产生的null,必须通过调试的方式找到。

在Java 14及更高版本中,当上述代码抛出空指针异常时,异常信息将包括调用栈中的详细位置:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.morris.java17.A.getB()" because "a" is null
	at com.morris.java17.NullPointerDemo.main(NullPointerDemo.java:10)
  • 1.
  • 2.

从异常结果可以清晰的看出是a这个对象为null。

注意这一特性主要影响的是异常信息的可读性,而不改变Java空指针异常的处理逻辑。