为什么 list.contains(null) 抛出空指针异常?

Moh*_*n M 2 java collections exception nullpointerexception

我有List<Long> countriesList其中包含Long国家/地区 ID 值。

List<UserRequests>现在我正在使用迭代一些列表streams

userRequests.stream().
    forEach(userRequest->
    {
        UserData=userRepository.findById(userRequest.getId()); //fine
        if (CollectionUtils.isNotEmpty(countriesList) && countriesList.contains(userRequest.getCountryId()))//getting NPE here
        {
            //do some operation
        }
    });
Run Code Online (Sandbox Code Playgroud)

我尝试通过评估各个语句来进行调试。我已确保countriesList有一些数据第一部分CollectionUtils.isNotEmpty(countriesList)正在返回trueuserRequest也不为 null 但userRequest.getCountryId()为 null。当我评估时countriesList.contains(userRequest.getCountryId()),我就到了Null pointer exception这里。为什么不false?我很困惑我做错了什么。默认list.contains(null)行为只是这样还是因为我在内部调用它stream()

为了简化起见,我创建了简单的列表并与null.

class Test {
    public static void main(String[] args) {
        List<Long> longList = List.of(1L, 2L, 3L);
        System.out.println("Comparing long list with null::" + longList.contains(null));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的异常:

Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:222)
    at java.base/java.util.ImmutableCollections$AbstractImmutableList.indexOf(ImmutableCollections.java:166)
    at java.base/java.util.ImmutableCollections$AbstractImmutableList.contains(ImmutableCollections.java:197)
    at com.test.Test.main(Test.java:26)
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

    List<Long> longList = new ArrayList<>();
    longList.add(1L);
    System.out.println("Comparing long list with null::" + longList.contains(null));
Run Code Online (Sandbox Code Playgroud)

为什么是打印呢false?为什么没有NullPointerException这里?

Ste*_*n C 9

为什么list.contains(null)会抛出空指针异常?

因为这是规范所说的可能发生的情况。

本案具体案理List.of(...)如下:

  1. 这些List.of方法被指定为生成不可修改的列表

  2. 不可修改的列表被指定为不允许使用null元素:

    “他们不允许空元素。尝试用元素创建它们null会导致NullPointerException。”

  3. javadoc状态List.contains

    “抛出:NullPointerException- 如果指定元素是null且此列表不允许null元素。

换句话说,您所看到的是指定的行为......而不是不正确或反复无常的实现的结果。

对于您正在搜索的情况countryList...这将取决于实际的List实现类。List但规范中有一个明确的预期,contains即如果您尝试搜索 ,某些null类型的列表可能会抛出 NPE 。

(这是否是一个“糟糕的设计选择”是一个观点问题。但这没有实际意义。设计List选择是很久以前做出的,现在改变它们会造成太大的破坏性而无法考虑。此外,我怀疑你将使当前的 Java 设计团队相信null集合类型中的值是一个好主意。)