簡體   English   中英

為什么 list.contains(null) 會拋出 null 指針異常?

[英]Why list.contains(null) throwing null pointer exception?

我有List<Long> countriesList ,其中包含作為國家/地區 ID 的Long值。

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

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

我試圖通過評估單個語句來進行調試。 我已經確保countriesList有一些數據第一部分CollectionUtils.isNotEmpty(countriesList)正在返回true userRequest是 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));
    }
}

這是我得到的例外:

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)

但如果我這樣做:

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

為什么打印是false的? 為什么這里沒有NullPointerException

來自 java.util.List 的API文檔:

一些列表實現對它們可能包含的元素有限制。 例如,有些實現禁止 null 元素,有些實現對其元素的類型有限制。 嘗試添加不合格的元素會引發未經檢查的異常,通常是 NullPointerException 或 ClassCastException。 嘗試查詢不合格元素的存在可能會引發異常,或者它可能只是返回 false; 一些實現會表現出前一種行為,而另一些會表現出后者。 更一般地,嘗試對不合格元素進行操作,其完成不會導致將不合格元素插入到列表中,這可能會引發異常,也可能會成功,這取決於實現的選擇。 此類異常在此接口的規范中被標記為“可選”。

boolean 包含(對象 o)

如果此列表包含指定元素,則返回true 更正式地說,當且僅當此列表包含至少一個元素 e 滿足 Objects.equals(o, e) 時才返回 true。

指定者:

包含在接口集合中

參數:

o - 要測試其在此列表中的存在的元素

回報:

如果此列表包含指定元素,則為 true

拋出:

ClassCastException - 如果指定元素的類型與此列表不兼容(可選)

NullPointerException - 如果指定元素是 null 並且此列表不允許 null 元素(可選)

您的countriesList似乎屬於 List 類型,不接受null元素,例如由List.ofList.copyOf生成的元素

為什么list.contains(null)會拋出 null 指針異常?

因為這是規范所說的可能發生的事情。

List.of(...)情況的具體推理如下:

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

  2. 不可修改的列表被指定為不允許null元素:

    “他們不允許 null 元素。嘗試使用null元素創建它們會導致NullPointerException 。”

  3. List.containsjavadoc指出:

    “拋出: NullPointerException - 如果指定的元素是null並且此列表不允許null元素。

換句話說,您所看到的是指定的行為......而不是不正確或反復無常的實現的結果。

對於您正在搜索countryList ... 的情況,這將取決於實際的List實現 class。 但是List規范中有一個明確的期望,即如果您嘗試搜索contains某些類型的列表可能會引發null

(這是否是一個“糟糕的設計選擇”是一個見仁見智的問題。但這沒有實際意義List設計選擇是很久以前做出的,現在改變它們會破壞性太大而無法考慮。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM