我有一个基类,它以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();
}
}
...
}
答案 0 :(得分:2)
是的,使用Java.extend,您只能覆盖超类方法。您不能向生成的子类添加新的Java字段或新的java方法。
如果你的问题是关于如何做相当于JS&#34; new&#34;从java代码中获取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);
}
}