簡體   English   中英

findFirst拋出java.lang.NullPointerException

[英]findFirst throws java.lang.NullPointerException

我在下面有這個代碼。 即使我有一個鏈接的orElseGet調用, findfirst調用也會拋出NullPointerException

int numberOfRetry = 5;
String req = "abc";
String res =
    Stream.iterate(0, n -> n + 1).map(i -> {
        try {
            return req.substring(numberOfRetry - i);
        } catch (Exception e) {
            // log exception
        }
        return null;
    })
    .limit(1)
    .findFirst()
    .orElseGet(() -> "Exception");

但是,如果我進行過濾器調用,它可以正常工作,如下所示:

int numberOfRetry = 5;
String req = "abc";
String res =
    Stream.iterate(0, n -> n + 1).map(i -> {
        try {
            return req.substring(numberOfRetry - i);
        } catch (Exception e) {
            // log exception
        }
        return null;
    })
    .limit(1)
    .filter(Objects::nonNull)
    .findFirst()
    .orElseGet(() -> "Exception");

我想我們在某些情況下不能顯式地返回null ,並且乍一看這些情況並不十分清楚。 在第一種情況下,它返回一個帶有null元素的stream ,它拋出NullPointerException ,在第二種情況下,它返回一個工作正常的空流。

您的代碼顯式返回null

return null

根據Optional.findFirst的規范,此后拋出NPE,其中包括:

 @throws NullPointerException if the element selected is null Optional<T> findFirst(); 

此外,澄清代碼控制甚至無法到達orElseGet部分,無論如何假設它在Optional (無論是空的還是有一些值)上工作。


幾點建議:

  • 不要忽略異常,特別是當你從中發現了最常見的異常時。
  • 避免在迭代中顯式返回null ,這似乎與你為什么要迭代相矛盾。
  • 當前代碼中更安全的一面,您可以使用filter僅過濾非null對象

     Stream.iterate(0, n -> n + 1).map(i -> { try { return req.substring(numberOfRetry - i); } catch (Exception e) { err.add(e); } return null; }) .filter(Objects::nonNull) .limit(1) .findFirst() .orElse("Exception"); 

當你這樣做時,你認為會發生什么:

System.out.println(req.substring(numberOfRetry - i));

i第一次是zero 將拋出一個越界異常 - 你捕獲並返回null ; 所以你有一個你調用了findFirstStream.of(null) - 它被記錄為拋出NullPointerException是元素為null的情況。

findFirstjavadoc

拋出:NullPointerException - 如果選擇的元素為null

Optional無法區分“存在但無效”和“不存在”

這是因為您在map函數中返回null 嘗試在map操作后添加.filter(s -> s != null)

暫無
暫無

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

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