I have a base class, that takes Entity
as its constructor argument. I extend this base class in JavaScript, and it looks like this:
Java.extend(BaseClass, {
someAbstractMethod : function() { ... },
someAdditionalField : ...,
etc
})
As far as I understood, I cannot use the additional fields / methods if I have instance of it as a Java object, but I can if it is a JavaScript object. So how do I instantiate this class as JS object with 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();
}
}
...
}
Yes, with Java.extend, you can only override super class methods. You cannot add new Java fields or new java methods to the generated subclass.
If your question is about how to do equivalent of JS "new" of a javascript function from java code, then:
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"));
}
}
See also: https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/JSObject.html
To create an instance of Java subclass defined with Java.extend, you can define a script function that will create Java object. You can invoke that function from java code either via Invocable.invokeFunction or JSObject.call.
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);
}
}