Java 8 begann zu erscheinen und brachte eine neue Funktion mit: Verwenden Sie den Lambda-Ausdruck (JSR-335) für die funktionale Programmierung. Heute werden wir einen Teil von Lambda: Virtual Extension, auch als Defender -Methode bezeichnet. Mit dieser Funktion können Sie die Methode zur Bereitstellung von Methoden in der Schnittstellendefinition implementieren. Sie können beispielsweise eine Methode für vorhandene Schnittstellen (z. B. Liste und Karte) definieren, damit andere Entwickler diese Methoden nicht wieder implementieren müssen, was ein bisschen wie abstrakt ist, aber tatsächlich eine Schnittstelle ist. Natürlich ist Java 8 theoretisch mit vorhandenen Bibliotheken kompatibel.
Die virtuelle Erweiterungsmethode verleiht Java mehrere Vererbungsmerkmale. Vielleicht können Sie den Schatten eines multiplen Vererbung durch diese Funktion sehen. Sie können jedoch die Vererbung des Instanzzustands simulieren. Ich werde das Erbe des Staates durch Mixin im nächsten Artikel ausführlich beschreiben.
Was wird in Mixin gemischt?
Das Mischen ist eine abstrakte Klasse einer Kombination. Wenn Sie beispielsweise eine Klasse haben, um "Pferd" anzuzeigen, können Sie diese Klasse instanziieren, um ein Beispiel für "Pferd" zu erstellen und sie dann wie "Garage" und "Garten" zu erweitern.
Val myhouse = neues Haus mit Garage mit Garten
Aus Mixin -Vererbung ist keine spezifische Spezifikation. Dies ist nur eine Methode, mit der verschiedene Funktionen zu vorhandenen Kategorien hinzugefügt werden. In OOP mit Mixin haben Sie die Lesbarkeit der Klasse durch sie.
Zum Beispiel gibt es eine Mixin -Methode im Socketserver -Modul von Python.
Class ForkingSpServer (ForkingMixin, UDPServer): PassClass ForkingCpServer (ForkingMixin, TCpServer): Pass -Klasse ThreadingUdpserver (ThreadMixin): PassClass ThreadingtCpServer (ThreadingMixin, TCpServer): Pass: Pass: Pass): Pass -Pass: Pass: Pass)
Was ist eine virtuelle Erweiterungsmethode?
Java 8 wird das Konzept der virtuellen Erweiterung einführen, die auch als Public Defender -Methode bezeichnet wird.
VEM zielt darauf ab, die Standardmethode für die Java -Schnittstelle anzugeben. Eine solche dritte Bibliothek wie Hibernate muss nicht alle Methoden dieser Sammel -APIs wiederholen, da sie einige Standardmethoden bereitgestellt hat.
Das Folgende ist ein Beispiel dafür, wie die Methode in der Schnittstelle definiert wird:
Öffentliche Schnittstelle Sammlung <T> erweitert iterable <t> {<R> Sammlung <R> Filter (Prädikat <T> P) Standard {Rückgabesammlungen.
Java 8s gemischte Simulation
Jetzt kommen wir durch VEM einen gemischten Effekt, aber im Voraus warnen wir: Bitte verwenden Sie bei der Arbeit nicht!
Die folgende Implementierung ist kein Thread -Safe, und es kann ein Problem der Speicherverletzung vorhanden sein, was vom HashCode abhängt und die in der Klasse definierten Methoden entspricht.
Zunächst definieren wir eine Definition einer Methode (simulierte Zustandsbohne) und stellen die Methode bereit:
Public interface Switchablemixin {boolean isActivated () Standard {return switchables.ISCTIVATED (this);
Dann definieren wir eine Werkzeugklasse, die eine Karteninstanz enthält, um die Assoziation von Instanzen und Status zu speichern.
Öffentliche Klassenschalter {private statische Karte <SwitchableMixin, SwitchableDevicestate> Switch_States = New HashMap <() (); Aktivität;} öffentliche statische Void -SetActivated (SwitchableMixin -Gerät, boolean aktiviert) {SwitchableDeVicestate = Switch_States.get (Gerät); .ACTIVATED = ACTIVATED;} private statische Klasse SwitchabledEvicestate {private boolean aktiviert;}}
Hier ist ein Anwendungsfall, der das Erbe des Staates hervorhebt:
Private statische Klasse Gerät {} private statische Klasse devicea erweitert Geräte implementiert Switchablemixin {} private statische Klasse Geräte erweitert Geräte imp Leter SwitchableMixin {}
"Völlig andere Dinge"
Die obige Implementierung scheint normal zu sein, aber der Java -Spracharchitekt von Oracle, Brian Goetz, stellte mir die Frage, dass die aktuelle Implementierung nicht funktionieren kann (vorausgesetzt, die Sicherheit und das Leckage von Threads wurden gelöst)
Schnittstelle FakeBrokenmixin {statische Karte <fakeBrokenmixin, String> BackingMap = Sammlungen. put (this, name);}} Schnittstelle x erweitert runnable, fakeBrokenmixin {} x makex () {return () -> {System.println ("x");}; (); x1.setName ("x1");
Welches Ergebnis werden Sie erraten, dass dieser Code nach der Ausführung angezeigt wird?
Zweifellösung
Auf den ersten Blick gibt es kein Problem mit diesem Implementierungscode. X ist eine Schnittstelle, die nur eine Methode enthält, da GetName und SetName bereits die Standarddefinition haben, aber die Auslaufmethode der ablaufbaren Schnittstelle ist nicht definiert. Implementierung der Laufmethode. Das Ergebnis, das Sie dieses Programm nach der Ausführung wünschen, lautet daher:
X1x2
Wenn Sie den Anruf der GetName -Methode löschen, wird das Ausführungsergebnis:
MyTest $ 1@30Ae8764myTest $ 1@123ACF34
Diese beiden Zeilen zeigen, dass die Ausführung der Makex-Methode aus zwei verschiedenen Instanzen stammt, und zu diesem Zeitpunkt wird die aktuelle OpenJDK 8 generiert (hier verwende ich OpenJDK 8 24.0-B07).
In jedem Fall spiegelt der aktuelle OpenJDK 8 das endgültige Java 8-Verhalten wider.
X2x2
Wenn Sie die GetName -Methode nicht aufrufen, wird sie angezeigt:
MyTest $ $ lambda $ 1@5506D4EamyTest $ $ lambda $ 1@5506D4EA
Jede Calling Makex -Methode scheint eine Singles -Instanz aus derselben anonymen internen Klasse zu sein.
Da während der Zusammenstellung der Lambda -Ausdruck keine vollständige Übersetzung erlebt hat, wurde dieser Übersetzungsprozess während der Zusammenstellung und der Laufzeit abgeschlossen. Diese Anweisung enthält alle notwendigen Meta -Informationen über den Labda -Ausdruck zur Laufzeit. Einschließlich des Method -Namens, Eingangs- und Ausgangstyps sowie einer Methode namens Bootstrap. Die Bootstrap -Methode wird verwendet, um die Instanz des Empfangens dieser Methode zu definieren.
Zurück zur Frage, gerade jetzt wurde der Lambda -Ausdruck zu einer privaten statischen Methode () -> {System.out.println ("x");} wurde auf myTest übertragen:
Private static void lambda $ 0 () {System.out.println ("x");}
Wenn Sie den Parameter des privaten Parameters mit dem Javap-Gegenkompilierungsgerät verwenden und diese Methode sehen können, können Sie auch den Parameter -c verwenden, um eine vollständigere Konvertierung anzuzeigen.
Wenn Sie das Programm ausführen, ruft JVM Lambda Metafactory -Methode auf, um zu versuchen, die aufgerufenen Anweisungen zu erklären. In unserem Beispiel erzeugt die Lambda -Methode eine Instanz eines X und verknüpft die Lambda $ -Methode dynamisch mit der Lambda $ -Methode Im Speicher ist die Instanz Ihres zweiten Anrufs das gleiche wie beim ersten Mal.
Hast du es repariert? Gibt es eine Lösung?
Es gibt keine direkte Reparatur oder Lösung für dieses Problem. Obwohl das Java 8-Programm von Oracle Standards-XdlambDatomethod Standard ist, da dieser Parameter nicht Teil der JVM-Spezifikation ist, ist die Implementierung verschiedener Lieferanten und JVM unterschiedlich. Für einen Lambda -Ausdruck können Sie nur erwarten, dass Sie Ihre Schnittstellenmethode in der Klasse implementieren können.
Andere Methoden
Obwohl unsere Nachahmung von Mixin nicht mit Java 8 kompatibel sein kann, ist es dennoch möglich, mehrere Dienste durch mehrfache Erbschaft und Ernennung hinzuzufügen, um zu existieren. Diese Methode ist virtuelles Feldmuster (virtueller Feldmodus).
Schauen Sie sich also unseren Schaltbar an.
Schnittstelle umschaltbar {boolean isActive ();
Wir benötigen eine schaltbare Schnittstelle und bieten eine zusätzliche Abstraktionsmethode zur Rückkehr zur schaltbaren Implementierung. Die integrierte Methode enthält die Standarddefinition.
Public Interface Switchable View erweitert {Switchable GetSwitchable ();
Als nächstes erstellen wir eine vollständige schaltbare Implementierung:
Öffentliche Klasse SwitchableImpl implementiert schaltbar {private boolean active;
Dies ist ein Beispiel für unseren virtuellen Feldmodus:
Öffentliche Klasse {} öffentliche Klasse Devicea erweitert Geräte implementiert SwitchableView {private Switchable SwitchableImpl (); Schaltbar getSwitchable () {return switchable;}}
abschließend
In diesem Artikel verwenden wir zwei Methoden, um mehrere Dienste über die virtuelle Erweiterungsmethode von Java 8 hinzuzufügen. Die erste Methode verwendet eine Karte, um den Instanzzustand zu speichern. Eine andere Methode besteht darin, einen virtuellen Feldmodus zu verwenden, um das endgültige Implementierungsbeispiel über einen abstrakten Getter zurückzugeben. Die zweite Methode ist unabhängiger und sicherer.
Die virtuelle Erweiterungsmethode ist das neue Merkmal von Java.