:: (doppelter Doppelpunkt) operator in Java 8
Ich erforschen, wurde die Java-8-Quelle und fand diese Besondere Teil des Codes sehr überraschend:
//defined in IntPipeline.java
@Override
public final OptionalInt reduce(IntBinaryOperator op) {
return evaluate(ReduceOps.makeInt(op));
}
@Override
public final OptionalInt max() {
return reduce(Math::max); //this is the gotcha line
}
//defined in Math.java
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Ist Math::max
so etwas wie eine Methode, die Zeiger? Wie sieht ein normaler static
- Methode konvertiert werden, um IntBinaryOperator
?
Es ist syntaktischer Zucker, um die compiler-automatische Generierung von interface-Implementierungen basiert auf der Funktion, die Sie (, um die ganze lambda-Ding einfacher zu verwenden mit den bestehenden code-Basen).
java.dzone.com/articles/java-lambda-expressions-vs helfen könnte, schaue nicht zu tief in das Thema
es ist nicht genau "syntaktischen Zucker", es sei denn, Sie können sagen, was. d.h. "x ist syntaktischer Zucker für y".
es erzeugt ein neues Objekt der lambda jedes mal ich es verwenden.
Lambdas und Methode Verweise sind nicht "plain old anonyme innere Klassen". Siehe programmers.stackexchange.com/a/181743/59134 . Ja, falls notwendig, neue Klassen und Instanzen erstellt werden on-the-fly, wenn nötig, aber nur, wenn nötig.
java.dzone.com/articles/java-lambda-expressions-vs helfen könnte, schaue nicht zu tief in das Thema
es ist nicht genau "syntaktischen Zucker", es sei denn, Sie können sagen, was. d.h. "x ist syntaktischer Zucker für y".
es erzeugt ein neues Objekt der lambda jedes mal ich es verwenden.
TestingLambda$$Lambda$2/8460669
und TestingLambda$$Lambda$3/11043253
erstellt wurden, auf zwei Anrufungen.Lambdas und Methode Verweise sind nicht "plain old anonyme innere Klassen". Siehe programmers.stackexchange.com/a/181743/59134 . Ja, falls notwendig, neue Klassen und Instanzen erstellt werden on-the-fly, wenn nötig, aber nur, wenn nötig.
InformationsquelleAutor Narendra Pathai | 2013-11-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Normalerweise würde ein Anruf die
reduce
Methode mitMath.max(int, int)
wie folgt:Erfordert eine Menge syntax nur für den Aufruf
Math.max
. Das ist, wo die lambda-Ausdrücke ins Spiel kommen. Seit Java 8 ist es erlaubt, das gleiche zu tun in einem viel kürzeren Weg:Wie funktioniert das? Der java-compiler "erkennt", dass Sie möchten, implementieren Sie eine Methode akzeptiert zwei
int
s und gibt eineint
. Dies entspricht der formale Parameter die eine und einzige Methode der SchnittstelleIntBinaryOperator
(die parameter der Methodereduce
Sie anrufen möchten). Damit der compiler erledigt den rest für Sie - es wird einfach nur angenommen, die Sie umsetzen wollenIntBinaryOperator
.Aber als
Math.max(int, int)
selbst erfüllt die formalen Anforderungen derIntBinaryOperator
, kann es direkt verwendet werden. Da Java 7-keine syntax, die es erlaubt, eine Methode, die sich selbst als argument übergeben (Sie können nur pass-Methode Ergebnisse, aber nie die Methode Referenzen), die::
syntax, die eingeführt wurde in Java 8 um die Referenz-Methoden:Beachten Sie, dass dies vom compiler interpretiert werden, nicht von der JVM zur Laufzeit! Obwohl es produziert verschiedene bytecodes für alle drei code snippets, sind Sie semantisch gleich, so dass die letzten beiden können als kurze (und wahrscheinlich effizienter) Versionen der
IntBinaryOperator
Umsetzung oben!(Siehe auch Übersetzung von Lambda-Ausdrücken)
InformationsquelleAutor isnot2bad
::
heißt Methode Referenz. Es ist im Grunde ein Verweis auf eine einzelne Methode. I. e. es bezieht sich auf eine bestehende Methode durch name.Kurze Erklärung:
Unten ist ein Beispiel für einen Verweis auf eine statische Methode:
square
übergeben werden können, wie Objekt-Referenzen und ausgelöst, wenn benötigt. In der Tat, es kann genauso gut als ein Verweis auf die "normalen" Methoden von Objekten alsstatic
lieben. Zum Beispiel:Function
oben ist ein funktionale Schnittstelle. Um vollständig zu verstehen::
ist es wichtig zu verstehen, funktionale Schnittstellen als gut. Klar, ein funktionale Schnittstelle ist ein interface mit nur einer abstrakten Methode.Beispiele von funktionalen Schnittstellen sind
Runnable
,Callable
, undActionListener
.Function
oben ist ein funktionales interface mit nur einer Methode:apply
. Es dauert ein argument und ein Ergebnis erzeugt.Der Grund, warum
::
s sind genial ist dass:E. g. statt zu schreiben die lambda-Körper
Können Sie einfach tun
Zur Laufzeit werden diese zwei
square
Methoden verhält sich genauso wie jeder andere. Der bytecode kann oder kann nicht das gleiche (obwohl, für den oben genannten Fall, für den gleichen bytecode erzeugt wird; kompilieren Sie die oben und prüfen Sie mitjavap -c
).Die einzige wichtige Kriterium zu erfüllen ist: die Methode, die Sie liefern sollten, haben eine ähnliche Signatur der Methode der funktionalen Schnittstelle, die Sie verwenden, die als Objekt-Referenz.
Die unten ist illegal:
square
erwartet ein argument und gibt einedouble
. Dieget
Methode in Lieferant gibt einen Wert zurück, nimmt aber nicht ein argument. So, dies führt zu einem Fehler.Eine Methode, die Referenz bezieht sich auf die Methode der funktionalen Schnittstelle. (Wie erwähnt, funktionale Schnittstellen kann jeweils nur eine Methode).
Einige weitere Beispiele: die
accept
Methode in Verbraucher nimmt eine Eingabe, aber nichts zurückgibt.Oben
getRandom
übernimmt keine Argumente und gibt einedouble
. So eine funktionale Schnittstelle, die erfüllt die Kriterien von: nehmen kein argument und zurückdouble
verwendet werden kann.Anderes Beispiel:
Bei parametrisierten Typen:
Methode Referenzen können verschiedene Stile haben, aber im Grunde sind Sie alle das gleiche bedeuten und kann einfach visualisiert werden, wie Lambda-Ausdrücke:
ClassName::methName
)instanceRef::methName
)super::methName
)ClassName::methName
)ClassName::new
)TypeName[]::new
)Weitere Referenz, siehe http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html.
InformationsquelleAutor Jatin
Ja, das ist wahr. Die
::
- operator wird verwendet für eine Methode verweisen. So kann man extrahieren statische Methoden aus Klassen, die durch die Nutzung oder Methoden von Objekten. Der gleiche operator kann verwendet werden, auch für Konstruktoren. Alle Fälle, die hier erwähnt sind exemplarisch in Codebeispiel unten.Die offizielle Dokumentation von Oracle finden hier.
Können Sie eine bessere übersicht über die JDK-8 änderungen in diese Artikel. In der Methode/Konstruktor verweisen auf Abschnitt ein code-Beispiel:
eine gute Erklärung ist auch hier: doanduyhai.wordpress.com/2012/07/14/...
ist Aufruf und die definition der Methode, der wäre wie
public static void method(IntBinaryOperator op){System.out.println(op.applyAsInt(1, 2));}
. Das ist, wie es eingesetzt wird.Für diejenigen, die vertraut mit C# ähnlich ist es mit DelegateType d = new DelegateType(MethodName);
InformationsquelleAutor Olimpiu POP
::
ist ein new-operator enthalten, die in Java 8, die verwendet wird, zu finden eine Methode einer bestehenden Klasse. Sie können sich statische Methoden nicht-statische Methoden einer Klasse.Für die Vermittlung von statischen Methoden, die syntax ist:
Für die Vermittlung nicht-statischen Methoden, die syntax ist
Und
Die einzige Voraussetzung für die Vermittlung ist eine Methode, die Methode besteht in einer funktionalen Schnittstelle, die kompatibel sein muss mit der Methode verweisen.
Methode verweist, die bei der Auswertung, erstellen Sie eine Instanz der funktionalen Schnittstelle.
Gefunden auf: http://www.speakingcs.com/2014/08/method-references-in-java-8.html
InformationsquelleAutor sreenath
Dies ist eine Methode, Referenz in Java 8. In der oracle-Dokumentation ist hier.
Wie in der Dokumentation erwähnt...
Noch ist compareByName. Daher werden Sie den Zugriff auf diese nicht-statische Methoden über die Referenz-operator ein Objekt verwenden. Wenn Sie statisch waren, könnten Sie den Namen der Klasse wie ComparisionProvider::someStaticMethod
InformationsquelleAutor david99world
Scheint es seine etwas spät aber hier sind meine zwei Cent. Ein lambda-Ausdruck dient zum erstellen von anonymen Methoden. Es tut nichts, sondern rufen Sie eine vorhandene Methode, aber es ist klarer zu beziehen, um die Methode direkt durch seinen Namen. Und Methode Referenz ermöglicht uns zu tun, dass mit der Methode-Referenz-operator
::
.Betrachten Sie die folgende einfache Klasse, bei dem jeder Mitarbeiter hat einen Namen und eine Klasse.
Nehmen wir an, wir haben eine Liste von Mitarbeitern zurückgegeben, die von einer bestimmten Methode, und wir möchten, Sortieren Sie die Mitarbeiter von Ihre grade. Wir wissen, wir können machen Verwendung von anonyme Klasse:
wo getDummyEmployee() ist eine Methode, wie:
Nun wissen wir, dass Komparator ist eine Funktionale Schnittstelle. Ein Funktionale Schnittstelle ist die, die genau eine abstrakte Methode (auch wenn es vielleicht enthalten ein oder mehrere standardmäßige oder statische Methoden). Lambda-Ausdruck liefert die Umsetzung von
@FunctionalInterface
so eine funktionale Schnittstelle kann nur über eine abstrakte Methode. Wir können lambda-Ausdruck als:Es scheint alles gut, aber was ist, wenn die Klasse
Employee
auch eine ähnliche Methode:In diesem Fall der name der Methode selbst wird mehr klar. Daher können wir direkt beziehen-Methode mithilfe der Methode als Referenz:
Als pro docs es gibt vier Arten von Methode Referenzen:
InformationsquelleAutor i_am_zero
:: Operator war eingeführt in java 8 für die Methoden-Referenzen. Eine Methode Referenz ist die Kurzform syntax für lambda-Ausdruck, der ausgeführt wird, nur EINE Methode. Hier ist die Allgemeine syntax einer Methode Referenz:
Wir wissen, dass wir verwenden können, lambda-Ausdrücke statt mit einer anonymen Klasse. Aber manchmal wird der lambda-Ausdruck ist wirklich nur ein Aufruf an eine Methode, zum Beispiel:
Machen den code übersichtlicher, können Sie diese lambda-Ausdruck in eine Methode, Referenz:
InformationsquelleAutor Vaibhav9518
Dem :: ist bekannt als Methode Referenzen. Angenommen, wir bezeichnen will calculatePrice Methode der Klasse Kaufen. Dann können wir schreiben als:
Es kann auch gesehen werden als Kurzform des Schreibens der lambda-Ausdruck, Weil die Methode Referenzen umgewandelt werden lambda-Ausdrücke.
InformationsquelleAutor Sonu
Zur Laufzeit Verhalten Sie sich a genau die gleiche.Der bytecode kann/nicht gleichzeitig (Für oben Incase,es erzeugt die gleiche bytecode(complie oben und check javaap -c;))
Zur Laufzeit Verhalten Sie sich a genau die gleiche.Methode(math::max); es erzeugt die gleiche Mathematik (complie oben und check javap -c;))
InformationsquelleAutor Alfa khatoon
return reduce(Math::max);
ist NICHT GLEICH zureturn reduce(max());
Aber es bedeutet, so etwas wie dieses:
Können Sie nur sparen 47 Tastenanschläge wenn Sie schreiben, wie diese
InformationsquelleAutor Jude Niroshan
In java-8-Streams Reducer in einfach funktioniert, ist eine Funktion, die zwei Werte als Eingabe und gibt das Ergebnis nach einigen Berechnungen. dieses Ergebnis ist die fed in der nächsten iteration.
im Fall von Math:max-Funktion, Methode hält die Rückkehr max zwei Werte übergeben und am Ende haben Sie die größte Zahl in der hand.
InformationsquelleAutor Pramod
Da viele der Antworten hier gut erklärt
::
Verhalten, außerdem möchte ich klarstellen, dass::
Betreiber nicht brauchen zu haben, die genau dieselbe Signatur wie das vorlegende Funktionale Schnittstelle, wenn es verwendet wird, für Instanz-Variablen. Nehmen wir an, wir brauchen eine BinaryOperator die Art der TestObject. In der traditionellen Art und Weise umgesetzt sein, wie dies:Wie Sie sehen in anonymisierter Umsetzung erfordert zwei TestObject argument und gibt eine TestObject-Objekt als gut. Zur Erfüllung dieser Bedingung durch die Verwendung
::
- operator wir beginnen mit einer statischen Methode:und dann rufen:
Ok, es kompiliert einwandfrei. Was ist, wenn wir brauchen eine Instanz-Methode? Lässt update-Testobjekt mit Instanz-Methode:
Nun können wir den Zugriff auf Instanz-wie folgt:
Dieser code kompiliert problemlos, aber unten nicht:
Mein eclipse mir sagen, "Cannot make a static reference to the non-static Methode testInstance(TestObject, TestObject), von der Art Testobjekt ..."
Fair genug sein, eine Instanz-Methode, aber wenn wir die überlastung
testInstance
wie folgt:Und rufen:
Wird der code einfach kompilieren in Ordnung. Denn es wird call
testInstance
mit der einzelnen parameter statt Doppel. Ok, so was passiert unseren beiden parameter? Ermöglicht Ausdruck und siehe:Die Ausgabe:
Ok, so JVM ist smart genug, um param1.testInstance(param2). Können wir
testInstance
aus der anderen Quelle aber nicht TestObject, d.h.:Und rufen:
Es wird einfach nicht kompiliert werden und der compiler wird sagen: "Der Typ TestUtil nicht definieren testInstance(TestObject, TestObject)". Also compiler suchen für einen statischen Verweis, wenn es nicht vom gleichen Typ sind. Ok was ist Polymorphismus? Wenn wir entfernen die letzten Modifikatoren und fügen Sie unsere SubTestObject Klasse:
Und rufen:
Wird es nicht kompilieren als gut, der compiler wird immer noch so Aussehen, für statische Referenz. Aber unten code kompilieren in Ordnung, da es vorbei ist-ein-test:
InformationsquelleAutor HRgiger
In älteren Java-Versionen, anstelle von "::" oder lambd, die Sie verwenden können:
Oder der übergabe an die Methode:
InformationsquelleAutor Kamil Tomasz Jarmusik
So sehe ich hier Tonnen von Antworten, die sind ehrlich gesagt zu kompliziert, und das ist eine Untertreibung.
Ist die Antwort ziemlich einfach: : es ist als eine Methode bezeichnet, Verweise https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Damit ich nicht copy-paste, auf den link, finden Sie alle Informationen, wenn Sie nach unten scrollen, um den Tisch.
Nun, werfen wir einen kurzen Blick auf das, was ist eine Methode Referenzen:
A::B etwas ersetzt folgende inline-lambda-Ausdruck: (params ...) -> A. B(params ...)
Korrelieren diese mit Ihren Fragen, es ist notwendig zu verstehen, ein java-lambda-Ausdruck. Das ist nicht schwer.
Inline-lambda-Ausdruck ist ähnlich wie ein definiert funktionale Schnittstelle (eine Schnittstelle, die hat keine mehr und keine weniger als 1-Methode).
Werfen wir einen kurzen Blick, was ich meine:
Interfacex gehe muss eine funktionale Schnittstelle. Eine funktionale Schnittstelle, die einzige Sache, was ist wichtig-interfacex gehe für diesen compiler ist, dass Sie das format definieren:
Interfacex gehe können sein:
oder diese
oder allgemeineren:
Nehmen wir den ersten Fall vorgestellt und die inline-lambda-Ausdruck definiert, dass wir früher.
Vor Java 8 war es definiert habe es ähnlich so:
Funktional, es ist die gleiche Sache. Der Unterschied liegt mehr darin, wie der compiler wahrnimmt.
Nun, haben wir einen Blick auf inline-lambda-Ausdruck, kehren wir zurück zur Methode Verweise (::). Lassen Sie uns sagen, Sie haben eine Klasse wie folgt aus:
Da Methode anyFunctions hat die gleichen Typen wie interfacex gehe callMe, können wir equivalate denen zwei mit einer Methode Referenz.
Können wir schreiben es so:
und das ist äquivalent zu :
Eine Coole Sache, und der Vorteil der Methode, die Referenzen sind, die auf den ersten, bis Sie ordnen Sie Variablen, Sie sind typeless. So können Sie diese als Parameter übergeben, um eine entsprechende Suche (hat die gleiche benutzerdefinierte Typen) funktionale Schnittstelle. Das ist genau das, was in Ihrem Fall
InformationsquelleAutor Nertan Lucian
Den vorherigen Antworten sind ziemlich komplett in Bezug auf das, was
::
Methode Referenz enthält. Zusammenfassend, es stellt eine Möglichkeit zum verweisen auf eine Methode(oder Konstruktor), ohne Sie auszuführen, und, wenn beurteilt wird, erstellt es eine Instanz der funktionalen Schnittstelle, die stellt die Ziel-Typ-Rahmen.Unten sind zwei Beispiele zu finden, ein Objekt mit dem max-Wert in einer
ArrayList
MIT und OHNE den Einsatz von::
Methode Referenz. Erklärungen sind in den Kommentaren unten.OHNE den Einsatz von
::
MIT der Verwendung von
::
InformationsquelleAutor Liutong Chen
Fand ich diese Quelle sehr interessant.
In der Tat, es ist die Lambda , verwandelt sich in einen Doppelten Doppelpunkt.
Der Doppel-Doppelpunkt ist mehr lesbar.
Wir Folgen diesen Schritten:
SCHRITT1:
SCHRITT 2:
SCHRITT 3:
Person::getAge()
solltePerson::getAge
.InformationsquelleAutor Husam Bdr
Doppelten Doppelpunkt also :: operator ist die Einführung in Java 8 als eine Methode verweisen. Methode Referenz ist eine form der lambda-Ausdruck, der verwendet wird, um zu finden, die bestehende Verfahren durch seinen Namen.
classname::methodName
ex:-
Durch die Verwendung von Doppel-Doppelpunkt ::
InformationsquelleAutor ishant kulshreshtha