Wypróbowuję jakiś reaktywny kod Spring, a poniżej znajduje się odpowiedni fragment kodu
Supplier<Stream<Long>> longStreamSupplier = ()
-> LongStream.iterate(0,
nextLong -> nextLong + 1).boxed();
Flux<Long> fooIds = Flux.fromStream(longStreamSupplier);
Ostatnia linia powyżej podaje błąd kompilacji w Intellij IDE, mówiąc, że nie ma metody akceptującej typ.
Jeśli jednak przekonwertuję go na następujący:
Flux<Long> fooIds = Flux.fromStream(() -> LongStream
.iterate(0, nextLong -> nextLong + 1)
.boxed());
To działa dobrze. Dlaczego nie można zaakceptować zmiennej referencyjnej wskazującej na to samo wyrażenie lambda, które przekazuję w drugim fragmencie kodu?
2 odpowiedzi
Dzieje się tak, ponieważ zmienna longStreamSupplier
ma typ Y<X<A>>
, podczas gdy metoda oczekuje argumentu typu Y<X<? extends A>>
, a te typy nie są zamienne.
edytuj
Możesz zmienić typ zmiennej, aby pierwszy przykład został skompilowany,
Supplier<Stream<? extends Long>> longStreamSupplier = ..
Twój typ argumentu dla fromStream
jest nieprawidłowy w pierwszym przykładzie. W drugim fragmencie został poprawnie wydedukowany jako Supplier<Stream<? extends Long>>
, podczas gdy w pierwszym wyraźnie „zawęziłeś” go do czegoś, co nie jest akceptowane przez Flux.streamOf
.
Możesz naprawić pierwszy fragment kodu, pisząc:
Supplier<Stream<? extends Long>> longStreamSupplier = ()
-> LongStream.iterate(0,
nextLong -> nextLong + 1).boxed();
Flux<Long> stream = Flux.fromStream(longStreamSupplier);
Możesz zadać sobie pytanie
Dlaczego nie ma przeciążenia dla tej funkcji, która akceptuje jawnie
Supplier<Stream<T>>
zamiastSupplier<Stream<? extends T>>
.
Wynika to z wymazywania typu Java, rozważ następujące dwie funkcje:
private void foo(Supplier<Stream<? extends Long>> stream) {
}
private void foo(Supplier<Stream<Long>> stream) {
}
Podczas kompilacji, po usunięciu typu, pozostaje:
private void foo(Supplier stream) {
}
private void foo(Supplier stream) {
}
Co powoduje błąd kompilacji, ponieważ mamy dwie funkcje z identycznymi definicjami. Tak więc w przypadku Flux::fromStream
zaimplementowana jest bardziej elastyczna wersja.
Podobne pytania
Nowe pytania
java
Java to język programowania wysokiego poziomu. Użyj tego tagu, jeśli masz problemy z używaniem lub zrozumieniem samego języka. Ten tag jest rzadko używany samodzielnie i jest najczęściej używany w połączeniu z [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] i [maven].