7

从 Java 15 升级到 Java 16 时,由于空指针异常,我的一些单元测试开始失败。该问题是由传递给 Paths.get() api 的空值引起的。Java 16 中发生了什么变化以使其成为错误?

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

4

2 回答 2

17

从 Java 16 开始,内部调用 Path.of() 的 Paths.get() 的实现现在明确要求“第一个”路径元素为非 null。

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

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

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

于 2021-08-15T12:52:27.640 回答
2

Paths.get()如果or的第一个参数Path.of()是,这是一个预期的异常nullJava 16版本中修复了一个已知错误。
错误:链接

Jdk 16发行说明中也提到了这一点。关联

(fs) 当 Path.of 或 Paths.get 的第一个参数为 null 时不抛出 NullPointerException (JDK-8254876) core-libs/java.nio Path.of() 和 Paths.get() 方法
的 var args 形式已更改在此版本中,当第一个参数为 null时始终抛出NullPointerException。从历史上看,这些方法在使用多个参数调用时会错过对第一个参数的空检查。

代码流程:

  1. Paths.get内部调用Path.of。(路径.java

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

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

  4. 在该方法中,我们进行检查以确认第一个参数/路径不是 null

    Objects.requireNonNull(first);
    
  5. 当第一个参数为nullNPE 时抛出。(对象.java

    public static <T> T requireNonNull(T obj, String message) {
     if (obj == null)
         throw new NullPointerException(message);
     return obj;
    }
    
于 2021-08-21T12:40:44.543 回答