Nie można zastąpić lambda input -> getValueProvider().apply(input).getValue()
odwołaniem do metody bez zmiany semantyki.
Metoda referencyjna zastępuje wywołanie metody pojedynczej, więc nie może po prostu zastąpić wyrażenia lambda składającego się z więcej niż jednego wywołania metody.
Wyrażenie lambda postaci input -> getValueProvider().apply(input)
można zastąpić getValueProvider()::apply
, wtedy i tylko wtedy, gdy w czasie oceny getValueProvider()
nie ma znaczenia, w lambda tworzą sposób wywoływany jest w każdej ocenie ciała N natomiast dla metody odwoływać jest wywoływana tylko raz, a wynik przechwytywany.
ta jest podobna do różnicy pomiędzy x -> System.out.println(x)
i System.out::println
gdzie czytając zawartość pola System.out
dzieje się w różnym czasie, ale zazwyczaj nie ma znaczenia. Ale powinieneś być świadomy różnicy.
W powyższym przykładzie wywoływana jest trzecia metoda: getValue()
. Jedynym sposobem na wyrażenie tego za pomocą odniesień do metod wymaga funkcjonalnego interfejsu, takiego jak Function
, który ma takie metody, jak andThen
i/lub compose
. Jednak sposób, w jaki działa Java 8, wymagałby przekazania pierwszego odwołania do metody do interfejsu docelowego w celu wywołania metody łączenia, która w żaden sposób nie byłaby łatwiejsza do odczytania niż wyrażenie lambda, które masz teraz: ((Function<X,Y>)getValueProvider()::apply).andThen(Y::getValue)
gdzie Y
jest typem, apply(input)
zwraca.
Należy zauważyć, że zasada mówi: „Wymień lambdy z metody odwołuje kiedy możliwe”, który daje pokój powiedzieć: „Cóż, tutaj jest to niemożliwe”, jednak nie jestem pewien, jak wiele można go rozmowy "Rule" then ...
Będzie łatwiej, jeśli napiszesz więcej kodu ... –