Ich habe mit dem folgenden Problem konfrontiert. Ich möchte java.util.HashMap
und java.util.PriorityQueue
im Skript Nashorn verwenden, wo ich ein bestimmtes benutzerdefiniertes Objekt als Schlüssel in der HashMap verwenden muss, und auch% verwenden co_de%, um zu prüfen, ob ein Schlüssel in der Karte vorhanden ist (eine weitere Option besteht darin, zu prüfen, ob das Objekt in einer Sammlung enthalten ist (Objekt o)).
Also muss ich natürlich in meinem Objekt equals und hashCode implementieren, basierend auf einigen Feldwerten.
Zum Beispiel:
Versuche, JavaScript zu verwenden. Funktioniert nicht, weil JavaScript diese Methoden nicht hat. Sehen Sie sich Beispiel 1 und Beispiel 2
Erweiterung von java.lang.Object Beispiel 3 Funktioniert teilweise, Methoden werden aufgerufen. Aber
Implementieren meiner benutzerdefinierten Klasse in Java und Erweitern in JavaScript. Beispiel 4 Funktioniert. Brauche ich Nashorn, wenn ich Java benutzen muss?
BEARBEITEN 1
@Tomasz, danke. Habe alle erwähnten Links gesehen. Aber obwohl das etwas undokumentiert existiert. Fast gab mit Nashorn auf. Zu der folgenden Teillösung kam es, Methoden werden aufgerufen, Konstruktor wird verwendet, aber wie HashMap.containsKey()
in der other.from
-Methode gecastet wird, um Zugriff auf das equals
-Feld des ursprünglichen Objekts zu erhalten (Dieser Code erzeugt für jede Instanz eines Vertex unterschiedliche Klassen):
BEARBEITEN 2
Danke für Tomasz, wie er darauf hingewiesen hat: Jeder Aufruf der Funktion java.extend () mit einem klassenspezifischen Implementierungsobjekt erzeugt eine neue Java-Adapterklasse. Daher müssen wir einen Objekt-Extender haben und Objekte mit diesem einen Typ instanziieren, wie er in seinem Beispiel gezeigt hat. Ich habe es ein wenig modifiziert, so dass es Instanzen mit der gleichen Klasse entweder mit dem Factory- oder dem direkten Konstruktor erzeugt, da wir den gleichen Objekt-Extender verwenden
%Vor% Es gibt jedoch noch ein Problem, der Typ des Parameters von from
ist equals
, mit anderen Worten, die jdk.nashorn.javaadapters.java.lang.Object
und other
innerhalb this
sind unterschiedliche Typen. Gibt es eine Möglichkeit, equals
-Wert aus dem Objekt zu generieren oder an _from
zu übergeben?
DIE LÖSUNG
Siehe die Lösung für das Problem in der Antwort von Tomasz .
Tolle Arbeit Tomasz! Danke.
PS: Es ist sehr traurig, dass es in Nashorn keine einfache und direkte Möglichkeit gibt, equals
und equals
zu implementieren. Es wäre nützlich für das Prototyping. Vergleichen Sie das einfach mit diesem:)
In Rhino würden Sie verwenden:
%Vor%Damit die JavaScript-Methoden die gleichnamigen Java-Methoden von java.lang.Object überschreiben (siehe Referenz Ссылка )
Vielleicht gibt es ein ähnliches Konstrukt in Nashorn.
BEARBEITEN:
Sie können die Rhino-Syntax in Nashorn verwenden. Setzen Sie einfach die Zeile:
%Vor%Siehe: Ссылка
BEARBEITEN: (WIEDER)
Mit Nashorn scheint es viel komplizierter zu sein:
%Vor%Siehe Ссылка
Was ist interessanter, wenn Sie mehrere Instanzen wie folgt erstellen:
%Vor% Dann sind sie von der gleichen Klasse (ich erwartete, dass sie Instanzen von zwei anonymen Sonnenklas sen von Object
sind).
EIN TRICK:
Obwohl du in Nashorn nicht-abstrakte Klassen im laufenden Betrieb erweitern kannst, wie:
%Vor% Sie können auf diese Weise abstrakte Klassen oder Interfaces erweitern. (Und da jede anonyme Klasse, die eine Schnittstelle implementiert, auch Object erweitert, können Sie auch die Methoden equals
oder hashCode
überschreiben).
Um dies zu veranschaulichen, sollten Sie eine JavaScript-Prototyp-Klasse verwenden:
%Vor%Sie können nun seine "Java-Wrapped" -Instanzen wie folgt erstellen:
%Vor% Sie wissen, dass Sie eine leere Java-Schnittstelle erstellen können, um solche Wrapper zu aktivieren, ohne dass zusätzliche Methodenimplementierungen bereitgestellt werden müssen (wie compare
im obigen Beispiel mit Comparable
).
PROBLEM
Wie Sie bereits erwähnt haben, handelt es sich bei den oben dargestellten Objekten um Java-Objekte mit fester "Schnittstelle". Daher wird jede Methode oder jedes Feld aus umgebrochenem JavaScript-Objekt, das nicht ausdrücklich von implementierten Interfaces oder Klassen spezifiziert wurde, NICHT von JavaScript aus zugänglich sein.
DIE LÖSUNG
Nach einigem Tüfteln fand ich die Lösung für das obige Problem. Ein Schlüssel dazu ist jdk.nashorn.api.scripting.AbstractJSObject
class von Nashorn Scripting API.
Überlegen Sie, wir haben JSVertex "JavaScript-Klasse" (sehr ähnlich wie bereits oben dargestellt):
%Vor%Lassen Sie uns eine Funktion erstellen, die es ermöglicht, Java-Objekte so über jedes JavaScript-Objekt zu legen, dass jede gleichnamige Methode aus dem JavaScript-Objekt die entsprechende Java-Objekt-Methode "erweitert".
%Vor%Nachdem wir das alles geschrieben haben, sehen wir, dass es funktioniert.
Erstellen Sie einen Wrapper über das JSVertex-Objekt und führen Sie einige Tests durch:
%Vor%Die Ausgabe:
%Vor%Tags und Links javascript java equals hashcode nashorn