Paths.get() / Path.of() 在升级到 Java 16 时抛出 NullPointerException

Paths.get() / Path.of() throws NullPointerException on upgrade to Java 16

从 Java 15 升级到 Java 16 时,由于空指针异常,我的一些单元测试开始失败。该问题是由传递给 Paths.get() api 的空值引起的。 Java 16 中的哪些更改导致出现此错误?

我正在使用 OpenJDK 版本 16.0.2 并且 运行 在 macOS 上。

从 Java 16 开始,内部调用 Path.of() 的 Paths.get() 的实现现在明确要求 'first' 路径元素是非-null.

这是对 Java 15 的实现更改,但与规范一致。 java.nio.files 的包 javadoc 声明“除非另有说明,否则将 null 参数传递给构造函数或任何 class 的方法或此包中的接口将导致抛出 NullPointerException。”

可以考虑和改进此实现更改,因为它将不再隐藏出现在文件系统路径中的字符串值“null”,这可能不是预期的结果。

在这种情况下,单元测试由于未正确初始化模拟对象而中断。

Paths.get()Path.of() 的第一个参数是 null,这是预期的异常。有一个已知错误已作为 Java 16 版本的一部分修复。
错误:link

Jdk16 发行说明中也提到了这一点。 link

(fs) NullPointerException Not Thrown When First Argument to Path.of or Paths.get Is null (JDK-8254876)
core-libs/java.nio The var args form of Path.of() and Paths.get() method are changed in this release to throw NullPointerException consistently when the first parameter is null. Historically these methods missed a null check on the first parameter when invoked with more than one parameter.

代码流:

  1. Paths.get 在内部调用 Path.of。 (Paths.java)

     public static Path get(String first, String... more) {
         return Path.of(first, more);
     }
    
  2. Path.of代码。 (Path.java)

    public static Path of(String first, String... more) {
     return FileSystems.getDefault().getPath(first, more);
    }
    
  3. 然后根据文件系统调用合适的 getPath 方法。
    一种。 WindowsFileSystem
    b. UnixFileSystem

  4. 在那个方法中我们有一个检查确认第一个 parameter/path 是 不是 null

    Objects.requireNonNull(first);
    
  5. 当第一个参数是null时,会抛出NPE。 (Objects.java)

    public static <T> T requireNonNull(T obj, String message) {
     if (obj == null)
         throw new NullPointerException(message);
     return obj;
    }