Überspringen Methodenverweise den Overhead der Lambda-Hülle? Könnten sie in der Zukunft?
Gemäß dem Java-Tutorial zu Methodenreferenzen :
Manchmal ... ruft ein Lambda-Ausdruck nur eine vorhandene Methode auf. In diesen Fällen ist es oft klarer, die vorhandene Methode namentlich zu bezeichnen. Mit Methodenreferenzen können Sie dies tun. Sie sind kompakte, leicht zu lesende Lambda-Ausdrücke für Methoden, die bereits einen Namen haben.
Ich bevorzuge die Lambda-Syntax aus mehreren Gründen der Methodenreferenzsyntax:
Lambdas sind klarer
Trotz der Behauptungen von Oracle finde ich die Lambda-Syntax besser lesbar als die Objektmethodenreferenz, da die Methodenreferenzsyntax nicht eindeutig ist:
Bar::foo
Rufen Sie eine statische Methode mit einem Argument für die Klasse x auf und übergeben Sie sie x?
x -> Bar.foo(x)
Oder rufen Sie eine Instanzmethode mit null Argumenten für x auf?
x -> x.foo()
Die Methodenreferenzsyntax könnte für beide stehen. Es verbirgt, was Ihr Code tatsächlich tut.
Lambdas sind sicherer
Wenn Sie Bar :: foo als Klassenmethode referenzieren und Bar später eine gleichnamige Instanzmethode hinzufügt (oder umgekehrt), wird Ihr Code nicht mehr kompiliert.
Sie können Lambdas konsequent verwenden
Sie können jede Funktion in ein Lambda einschließen, sodass Sie überall dieselbe Syntax konsistent verwenden können. Die Methodenreferenzsyntax funktioniert nicht bei Methoden, die primitive Arrays annehmen oder zurückgeben, geprüfte Ausnahmen auslösen oder denselben Methodennamen haben, der als Instanz und statische Methode verwendet wird (da die Methodenreferenzsyntax nicht eindeutig ist, welche Methode aufgerufen wird). . Sie funktionieren nicht, wenn Sie Methoden mit der gleichen Anzahl von Argumenten überladen haben, aber Sie sollten das sowieso nicht tun (siehe Punkt 41 von Josh Bloch), daher können wir das nicht mit Methodenreferenzen vergleichen.
Fazit
Wenn es dafür keine Leistungseinbußen gibt, bin ich versucht, die Warnung in meiner IDE auszuschalten und die Lambda-Syntax konsistent zu verwenden, ohne den gelegentlichen Methodenverweis in meinen Code zu streuen.
PS
Weder hier noch dort, aber in meinen Träumen sehen Objektmethodenreferenzen eher so aus und wenden ohne Lambda-Wrapper eine Aufrufdynamik auf die Methode direkt auf das Objekt an:
_.foo()
.map(_.acceptValue())
: Wenn ich mich nicht irre, sieht das der Scala-Syntax sehr ähnlich. Vielleicht versuchen Sie nur, die falsche Sprache zu verwenden.
System.out::println
an die forEach()
ganze Zeit ...?