Dieses Codebeispiel
%Vor%verstößt gegen die Sonarqube-Regel :
Ersetzen Sie lambdas wenn möglich durch Methodenreferenzen
ist es ein Sonar Bug? oder kann ich wirklich eine Methodenreferenz verwenden?
Sie können das Lambda input -> getValueProvider().apply(input).getValue()
nicht durch eine Methodenreferenz ersetzen, ohne die Semantik zu ändern.
Eine Methodenreferenz ersetzt einen einzelnen Methodenaufruf, sodass sie nicht einfach einen Lambda-Ausdruck ersetzen kann, der aus mehr als einem Methodenaufruf besteht.
Ein Lambda-Ausdruck der Form input -> getValueProvider().apply(input)
könnte durch getValueProvider()::apply
ersetzt werden, wenn und nur wenn die Auswertezeit von getValueProvider()
keine Rolle spielt, wie in der Lambda-Form die Methode bei jeder Lambda-Body-Auswertung aufgerufen wird Für die Methodenreferenz wird sie nur einmal aufgerufen und das Ergebnis wird erfasst.
Dies ist ähnlich dem Unterschied zwischen x -> System.out.println(x)
und System.out::println
, wo das Lesen des Inhalts des Feldes System.out
zu verschiedenen Zeiten geschieht, aber normalerweise spielt es keine Rolle. Aber Sie sollten sich des Unterschieds bewusst sein.
In Ihrem Beispiel wird eine dritte Methode getValue()
aufgerufen. Die einzige Möglichkeit, dies mit Methodenreferenzen auszudrücken, benötigt eine funktionale Schnittstelle wie Function
, die Methoden wie andThen
und / oder compose
hat. Die Funktionsweise von Java 8 würde jedoch erfordern, dass die erste Methodenreferenz auf die Zielschnittstelle übertragen wird, um die Kombinationsmethode aufzurufen, die in keiner Weise einfacher zu lesen ist als der Lambda-Ausdruck, den Sie jetzt haben: ((Function<X,Y>)getValueProvider()::apply).andThen(Y::getValue)
wobei Y
ist Der Typ apply(input)
gibt zurück.
Beachten Sie, dass in der Regel "Ersetzen Sie Lambdas durch Methodenreferenzen wenn möglich " angegeben ist. Sie können also sagen: "Nun, hier ist es unmöglich", aber ich bin mir nicht sicher, wie viel Sie sind kann es dann eine "Regel" nennen ...