Java 当我有一个代表 JS 函数的对象时,Nashorn 在 Java 中创建 JS 对象
Java Nashorn create JS object in Java, when I have an object representing JS function
我有一个基础 class,它将 Entity
作为其构造函数参数。我在 JavaScript 中扩展了这个基础 class,它看起来像这样:
Java.extend(BaseClass, {
someAbstractMethod : function() { ... },
someAdditionalField : ...,
etc
})
据我所知,如果我将它的实例作为 Java 对象,我将无法使用其他字段/方法,但如果它是 JavaScript 对象,我可以。那么如何使用 Java 代码将此 class 实例化为 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();
}
}
...
}
是的,使用 Java.extend,您只能覆盖超级 class 方法。您不能向生成的子 class.
添加新的 Java 字段或新的 java 方法
如果您的问题是关于如何从 java 代码中执行相当于 java 脚本函数的 JS "new",那么:
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 subclass 的实例,您可以定义将创建 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);
}
}
我有一个基础 class,它将 Entity
作为其构造函数参数。我在 JavaScript 中扩展了这个基础 class,它看起来像这样:
Java.extend(BaseClass, {
someAbstractMethod : function() { ... },
someAdditionalField : ...,
etc
})
据我所知,如果我将它的实例作为 Java 对象,我将无法使用其他字段/方法,但如果它是 JavaScript 对象,我可以。那么如何使用 Java 代码将此 class 实例化为 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();
}
}
...
}
是的,使用 Java.extend,您只能覆盖超级 class 方法。您不能向生成的子 class.
添加新的 Java 字段或新的 java 方法如果您的问题是关于如何从 java 代码中执行相当于 java 脚本函数的 JS "new",那么:
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 subclass 的实例,您可以定义将创建 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);
}
}