2016-07-07 6 views
0

Ich habe eine Basisklasse, die Entity als Konstruktorargument verwendet. Ich erweitere diese Basisklasse in JavaScript, und es sieht wie folgt aus:Java Nashorn JS-Objekt in Java erstellen, wenn ich ein Objekt habe, das JS-Funktion darstellt

Java.extend(BaseClass, { 
     someAbstractMethod : function() { ... }, 
     someAdditionalField : ..., 
     etc 
}) 

Soweit ich verstanden, ich nicht die zusätzlichen Felder/Methoden verwenden können, wenn ich Instanz davon als Java-Objekt haben, aber ich kann, wenn Es ist ein JavaScript-Objekt. Wie instanziiere ich diese Klasse als JS-Objekt mit Java-Code?

public class ScriptedEntity extends Entity implements Scripted<EntityScriptFunctions> { 

    private CompiledScript script; 
    private Object implemented_script_class; 
    private Object my_script_instance; 
    private Invocable invocable; 

    public ScriptedEntity(float x, float y, CompiledScript script) { 
     super(x, y); 
     invocable = (Invocable) script.getEngine(); 
     try { 
      implemented_script_class = script.eval(); 
      my_script_instance = invocable.invokeFunction("???", this); //'this' is the constructor argument 
     } catch (ScriptException | IllegalArgumentException | NoSuchMethodException | SecurityException e) { 
      e.printStackTrace(); 
     } 
    } 

    ... 

} 

Antwort

2

Ja, mit Java.extend können Sie nur Superklassenmethoden überschreiben. Sie können der generierten Unterklasse keine neuen Java-Felder oder neuen Java-Methoden hinzufügen.

Wenn Ihre Frage ist, wie äquivalent von JS „neuen“ einer JavaScript-Funktion von Java-Code zu tun, dann:

import javax.script.*; 
import jdk.nashorn.api.scripting.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    ScriptEngineManager m = new ScriptEngineManager(); 
    ScriptEngine e = m.getEngineByName("nashorn"); 
    e.eval("function Point(x, y) { this.x = x; this.y = y}"); 
    JSObject pointFunc = (JSObject)e.get("Point"); 
    JSObject pointObj = (JSObject)pointFunc.newObject(43, 55); 
    System.out.println(pointFunc.isInstance(pointObj)); 
    System.out.println(pointObj.getMember("x")); 
    System.out.println(pointObj.getMember("y")); 
    } 
} 

Siehe auch: https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/JSObject.html

Um eine Instanz von Java Unterklasse zu erstellen Mit Java.extend definiert, können Sie eine Skriptfunktion definieren, die ein Java-Objekt erstellt. Sie können diese Funktion über Javacode entweder über Invocable.invokeFunction oder JSObject.call aufrufen.

import java.util.*; 
import javax.script.*; 
import jdk.nashorn.api.scripting.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    ScriptEngineManager m = new ScriptEngineManager(); 
    ScriptEngine e = m.getEngineByName("nashorn"); 
    e.eval("var MyHashMap = Java.extend(java.util.HashMap, {})"); 
    e.eval("function createMyHashMap() { return new MyHashMap(); }"); 
    HashMap hm = (HashMap) ((Invocable)e).invokeFunction("createMyHashMap"); 
    System.out.println(hm); 
    } 
} 
Verwandte Themen