Ich möchte eine Funktionalität in einer Objektliste wie in C # mithilfe einer Erweiterungsmethode implementieren.
Etwas wie das:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Wie mache ich das in Java?
java
extension-methods
Fabio Milheiro
quelle
quelle
Antworten:
Java unterstützt keine Erweiterungsmethoden.
Stattdessen können Sie eine reguläre statische Methode erstellen oder eine eigene Klasse schreiben.
quelle
Erweiterungsmethoden sind nicht nur statische Methoden und nicht nur Convenience-Syntaxzucker, sondern auch ein recht leistungsfähiges Werkzeug. Die Hauptsache ist die Möglichkeit, verschiedene Methoden basierend auf der Instanziierung der Parameter verschiedener Generika zu überschreiben. Dies ähnelt den Typklassen von Haskell, und es sieht tatsächlich so aus, als wären sie in C #, um C # -Monaden (dh LINQ) zu unterstützen. Selbst wenn ich die LINQ-Syntax fallen lasse, weiß ich immer noch nicht, wie ich ähnliche Schnittstellen in Java implementieren kann.
Und ich denke nicht, dass es möglich ist, sie in Java zu implementieren, da Java die Semantik der Löschung von generischen Parametern löscht.
quelle
Project Lombok bietet eine Anmerkung
@ExtensionMethod
, mit der Sie die von Ihnen gewünschte Funktionalität erreichen können.quelle
java.lang.String
. Demonstration: http://manifold.systems/images/ExtensionMethod.mp4Technisch gesehen hat die C # -Erweiterung in Java keine Entsprechung. Wenn Sie solche Funktionen jedoch für einen saubereren Code und eine sauberere Wartbarkeit implementieren möchten, müssen Sie das Manifold-Framework verwenden.
quelle
Die XTend- Sprache - eine Super-Menge von Java, die zu Java-Quellcode 1 kompiliert wird - unterstützt dies.
quelle
Manifold bietet Java Erweiterungsmethoden im C # -Stil und verschiedene andere Funktionen. Im Gegensatz zu anderen Tools, hat Manifold keine Einschränkungen und nicht leiden von Problemen mit Generika, Lambda - Ausdrücke, IDE usw. Manifold bietet verschiedene andere Funktionen wie F # -Stil benutzerdefinierte Typen , Typoskript-Stil strukturelle Schnittstellen und Javascript-Stil expando Typen .
Darüber hinaus bietet IntelliJ umfassende Unterstützung für Manifold über das Manifold- Plugin .
Manifold ist ein Open Source-Projekt, das auf github verfügbar ist .
quelle
Eine weitere Option ist die Verwendung von ForwardingXXX- Klassen aus der Google-Guava-Bibliothek.
quelle
Java hat keine solche Funktion. Stattdessen können Sie entweder eine reguläre Unterklasse Ihrer Listenimplementierung erstellen oder eine anonyme innere Klasse erstellen:
Das Problem besteht darin, diese Methode aufzurufen. Sie können es "an Ort und Stelle" tun:
quelle
Es sieht so aus, als ob es eine kleine Chance gibt, dass Defender-Methoden (dh Standardmethoden) es in Java 8 schaffen. Soweit ich sie verstehe, erlauben sie jedoch nur den Autor eines
interface
, es rückwirkend zu erweitern, nicht willkürlichen Benutzern.Defender Methods + Interface Injection könnten dann Erweiterungsmethoden im C # -Stil vollständig implementieren, aber AFAICS, Interface Injection ist noch nicht einmal auf der Java 8-Roadmap.
quelle
Etwas spät zur Party in dieser Frage, aber falls jemand es nützlich findet, habe ich gerade eine Unterklasse erstellt:
quelle
Wir können die Implementierung von C # -Erweiterungsmethoden in Java mithilfe der seit Java 8 verfügbaren Standardmethodenimplementierung simulieren. Zunächst definieren wir eine Schnittstelle, über die wir über eine base () -Methode auf das Support-Objekt zugreifen können:
Wir geben null zurück, da Schnittstellen keinen Status haben können, dies muss jedoch später über einen Proxy behoben werden.
Der Entwickler von Erweiterungen müsste diese Schnittstelle um eine neue Schnittstelle erweitern, die Erweiterungsmethoden enthält. Angenommen, wir möchten einen forEach-Consumer auf der List-Oberfläche hinzufügen:
Da wir die Erweiterungsschnittstelle erweitern, können wir die base () -Methode innerhalb unserer Erweiterungsmethode aufrufen, um auf das Support-Objekt zuzugreifen, an das wir uns anhängen.
Die Erweiterungsschnittstelle muss über eine Factory-Methode verfügen, mit der eine Erweiterung eines bestimmten Unterstützungsobjekts erstellt wird:
Wir erstellen einen Proxy, der die Erweiterungsschnittstelle und die gesamte vom Typ des Unterstützungsobjekts implementierte Schnittstelle implementiert. Der dem Proxy übergebene Aufrufhandler würde alle Aufrufe an das Support-Objekt senden, mit Ausnahme der "base" -Methode, die das Support-Objekt zurückgeben muss, andernfalls gibt die Standardimplementierung null zurück:
Anschließend können wir die Extension.create () -Methode verwenden, um die Schnittstelle mit der Erweiterungsmethode an das Support-Objekt anzuhängen. Das Ergebnis ist ein Objekt, das in die Erweiterungsschnittstelle umgewandelt werden kann, über die wir weiterhin auf das Unterstützungsobjekt zugreifen können, das die base () -Methode aufruft. Nachdem die Referenz in die Erweiterungsschnittstelle umgewandelt wurde, können wir jetzt sicher die Erweiterungsmethoden aufrufen, die Zugriff auf das Unterstützungsobjekt haben können, sodass wir jetzt neue Methoden an das vorhandene Objekt anhängen können, jedoch nicht an den definierenden Typ:
Auf diese Weise können wir die Möglichkeit simulieren, Objekte in Java zu erweitern, indem wir ihnen neue Verträge hinzufügen, mit denen wir zusätzliche Methoden für die angegebenen Objekte aufrufen können.
Unten finden Sie den Code der Erweiterungsschnittstelle:
quelle
Man könnte das objektorientierte Designmuster des Dekorateurs verwenden . Ein Beispiel für dieses Muster, das in der Standardbibliothek von Java verwendet wird, ist der DataOutputStream .
Hier ist ein Code zum Erweitern der Funktionalität einer Liste:
PS Ich bin ein großer Fan von Kotlin . Es verfügt über Erweiterungsmethoden und läuft auch auf der JVM.
quelle
Sie können eine C # -ähnliche Erweiterungs- / Hilfsmethode erstellen, indem Sie (RE) die Collections-Schnittstelle implementieren und ein Beispiel für Java Collection hinzufügen:
quelle
Java
8 unterstützt jetzt Standardmethoden , die denC#
Erweiterungsmethoden ähneln .quelle