【问题标题】:Java Nashorn create JS object in Java, when I have an object representing JS function当我有一个代表 JS 函数的对象时,Java Nashorn 在 Java 中创建 JS 对象
【发布时间】:2016-07-07 09:04:46
【问题描述】:

我有一个基类,它将Entity 作为其构造函数参数。我在 JavaScript 中扩展了这个基类,它看起来像这样:

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

据我所知,如果我将其实例作为 Java 对象,我不能使用附加字段/方法,但如果它是 JavaScript 对象,我可以。那么如何用 Java 代码将这个类实例化为 JS 对象呢?

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();
        }
    }

    ...

}

【问题讨论】:

    标签: javascript java nashorn


    【解决方案1】:

    是的,使用 Java.extend,您只能覆盖超类方法。您不能向生成的子类添加新的 Java 字段或新的 Java 方法。

    如果您的问题是关于如何从 java 代码中做相当于 JS“新”的 javascript 函数,那么:

    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"));
      }
    }
    

    另请参阅:https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/JSObject.html

    要创建用 Java.extend 定义的 Java 子类的实例,您可以定义一个脚本函数来创建 Java 对象。您可以通过 Invocable.invokeFunction 或 JSObject.call 从 Java 代码调用该函数。

    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);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-01
      • 2016-03-13
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      相关资源
      最近更新 更多