Dies mag allgemein und trivial sein, aber ich habe anscheinend Probleme, eine konkrete Antwort zu finden. In C # gibt es ein Konzept von Delegaten, das sich stark auf die Idee von Funktionszeigern aus C ++ bezieht. Gibt es eine ähnliche Funktionalität in Java? Was ist der beste Weg, da Zeiger etwas fehlen? Und um klar zu sein, wir sprechen hier erstklassig.
java
pointers
delegates
function-pointers
Dreadwail
quelle
quelle
this::myMethod
ist semantisch dasselbe wie ein Lambda zu erstellenparamA, paramB -> this.myMethod(paramA, paramB)
.Antworten:
Das Java-Idiom für funktionszeigerähnliche Funktionen ist eine anonyme Klasse, die eine Schnittstelle implementiert, z
Update: Das Obige ist in Java-Versionen vor Java 8 erforderlich. Jetzt haben wir viel schönere Alternativen, nämlich Lambdas:
und Methodenreferenzen:
quelle
std::bind
, was Parameter an Funktionen bindet und ein aufrufbares Objekt zurückgibt. Ich kann nicht aus diesen Gründen verteidigen C, aber C ++ wirklich ist besser als Java für diesen.Sie können einen Funktionszeiger durch eine Schnittstelle ersetzen. Nehmen wir an, Sie möchten eine Sammlung durchlaufen und mit jedem Element etwas tun.
Dies ist die Schnittstelle, die wir an einige sagen könnten, CollectionUtils2.doFunc (Collection c, IFunction f).
Angenommen, wir haben eine Sammlung von Zahlen, und Sie möchten jedem Element 1 hinzufügen.
quelle
Sie können Reflexion verwenden, um es zu tun.
Übergeben Sie als Parameter das Objekt und den Methodennamen (als Zeichenfolge) und rufen Sie dann die Methode auf. Beispielsweise:
Und dann verwenden Sie es wie in:
Überprüfen Sie natürlich alle Ausnahmen und fügen Sie die erforderlichen Besetzungen hinzu.
quelle
Nein, Funktionen sind in Java keine erstklassigen Objekte. Sie können dasselbe tun, indem Sie eine Handlerklasse implementieren - so werden Rückrufe im Swing usw. implementiert.
Es gibt jedoch Vorschläge für Schließungen (der offizielle Name für das, worüber Sie sprechen) in zukünftigen Versionen von Java - Javaworld hat einen interessanten Artikel.
quelle
Dies erinnert an Steve Yegges Hinrichtung im Königreich der Substantive . Grundsätzlich heißt es, dass Java für jede Aktion ein Objekt benötigt und daher keine "Nur-Verb" -Entitäten wie Funktionszeiger hat.
quelle
Um ähnliche Funktionen zu erreichen, können Sie anonyme innere Klassen verwenden.
Wenn Sie eine Schnittstelle definieren würden
Foo
:Erstellen Sie eine Methode,
bar
die als Argument einen 'Funktionszeiger' erhält:Rufen Sie die Methode abschließend wie folgt auf:
quelle
Java8 hat Lambdas und Methodenreferenzen eingeführt . Also , wenn Ihre Funktion eine Spiel funktionale Schnittstelle (Sie selbst erstellen können) können Sie eine Methode Referenz in diesem Fall verwendet werden .
Java bietet eine Reihe allgemeiner Funktionsschnittstellen . Sie könnten jedoch Folgendes tun:
quelle
alias
public List<T> collect(T t) = Collections::collect
In Java gibt es so etwas nicht. Sie müssen Ihre Funktion in ein Objekt einschließen und den Verweis auf dieses Objekt übergeben, um den Verweis auf die Methode für dieses Objekt zu übergeben.
Syntaktisch kann dies bis zu einem gewissen Grad vereinfacht werden, indem an Ort und Stelle definierte anonyme Klassen oder anonyme Klassen verwendet werden, die als Mitgliedsvariablen der Klasse definiert sind.
Beispiel:
quelle
Ich habe Callback / Delegate-Unterstützung in Java mithilfe von Reflection implementiert. Details und Arbeitsquelle finden Sie auf meiner Website .
Wie es funktioniert
Wir haben eine Hauptklasse namens Callback mit einer verschachtelten Klasse namens WithParms. Die API, die den Rückruf benötigt, verwendet ein Callback-Objekt als Parameter und erstellt bei Bedarf einen Callback.WithParms als Methodenvariable. Da sehr viele Anwendungen dieses Objekts rekursiv sind, funktioniert dies sehr sauber.
Da die Leistung für mich immer noch eine hohe Priorität hat, wollte ich nicht verpflichtet sein, ein Wegwerfobjektarray zu erstellen, das die Parameter für jeden Aufruf enthält - schließlich kann es in einer großen Datenstruktur Tausende von Elementen geben und in einer Nachrichtenverarbeitung In diesem Szenario könnten wir am Ende Tausende von Datenstrukturen pro Sekunde verarbeiten.
Um threadsicher zu sein, muss das Parameterarray für jeden Aufruf der API-Methode eindeutig vorhanden sein, und aus Effizienzgründen sollte für jeden Aufruf des Rückrufs dasselbe verwendet werden. Ich brauchte ein zweites Objekt, dessen Erstellung billig wäre, um den Rückruf mit einem Parameterarray zum Aufrufen zu binden. In einigen Szenarien verfügt der Aufrufer jedoch aus anderen Gründen bereits über ein Parameterarray. Aus diesen beiden Gründen gehörte das Parameterarray nicht zum Callback-Objekt. Auch die Wahl des Aufrufs (Übergabe der Parameter als Array oder als einzelne Objekte) liegt in den Händen der API, die den Rückruf verwendet, um den Aufruf zu verwenden, der für das Innenleben am besten geeignet ist.
Die verschachtelte WithParms-Klasse ist also optional und dient zwei Zwecken: Sie enthält das für die Rückrufaufrufe erforderliche Parameterobjektarray und bietet 10 überladene invoke () -Methoden (mit 1 bis 10 Parametern), die das Parameterarray laden und dann Rufen Sie das Rückrufziel auf.
quelle
Überprüfen Sie die Abschlüsse, wie sie in der Lambdaj-Bibliothek implementiert wurden. Sie haben tatsächlich ein Verhalten, das C # -Delegierten sehr ähnlich ist:
http://code.google.com/p/lambdaj/wiki/Closures
quelle
Im Vergleich zu den meisten Leuten hier bin ich neu in Java, aber da ich keinen ähnlichen Vorschlag gesehen habe, kann ich eine andere Alternative vorschlagen. Ich bin mir nicht sicher, ob es eine gute Praxis ist oder nicht oder sogar vorher vorgeschlagen und ich habe es einfach nicht verstanden. Ich mag es einfach, weil ich denke, dass es selbstbeschreibend ist.
dann je nach anwendung zuweisen
etc.
und rufen Sie an
quelle