簡體   English   中英

可以在 Java 中傳遞指向 Lambda 的引用變量

[英]Can pass reference variable pointing to Lambda in Java

我嘗試了一些 Spring 反應式代碼,以下是相關的代碼段

Supplier<Stream<Long>> longStreamSupplier = ()
            -> LongStream.iterate(0,
                    nextLong -> nextLong + 1).boxed();

Flux<Long> fooIds = Flux.fromStream(longStreamSupplier); 

上面的最后一行給出了 Intellj IDE 中的編譯錯誤,表示沒有接受該類型的方法。

但是,如果我將其轉換為以下內容:

Flux<Long> fooIds = Flux.fromStream(() -> LongStream
                    .iterate(0, nextLong -> nextLong + 1)
                    .boxed());

這工作正常。 為什么它不能接受指向我在第二段代碼中傳遞的同一個 lambda 表達式的引用變量?

您的fromStream參數類型在第一個示例中是錯誤的。 在第二個片段中,它被正確地推導出為Supplier<Stream<? extends Long>> Supplier<Stream<? extends Long>> ,而在第一個中,您明確地將其“縮小”為Flux.streamOf不接受的Flux.streamOf

您可以通過編寫以下代碼來修復第一個片段:

        Supplier<Stream<? extends Long>> longStreamSupplier = ()
                -> LongStream.iterate(0,
                nextLong -> nextLong + 1).boxed();

        Flux<Long> stream = Flux.fromStream(longStreamSupplier);

你可能會問自己

為什么這個函數沒有一個顯式接受Supplier<Stream<T>>而不是Supplier<Stream<? extends T>>的重載Supplier<Stream<? extends T>> Supplier<Stream<? extends T>>

那是因為 Java 類型擦除,請考慮以下兩個函數:


    private void foo(Supplier<Stream<? extends  Long>> stream) {

    }
    private void foo(Supplier<Stream<Long>> stream) {

    }

編譯時,類型擦除后,我們剩下:


    private void foo(Supplier stream) {

    }
    private void foo(Supplier stream) {

    }

這會產生編譯錯誤,因為我們有兩個具有相同定義的函數。 所以在Flux::fromStream的情況下,實現了更靈活的版本。

這是因為longStreamSupplier變量的類型為Y<X<A>> ,而該方法需要一個類型為Y<X<? extends A>> Y<X<? extends A>> ,並且這些類型不可互換。

編輯

您可以更改變量類型以編譯第一個示例,

Supplier<Stream<? extends Long>> longStreamSupplier = ..

暫無
暫無

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

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