3

要从 JS 调用 Java,您可以使用Java.type. 有没有办法在 Bindings 中绑定一个 java 类?

所以替换:

scriptEngine.eval("Java.type('my.own.AwesomeObj')");

有类似的东西:

Bindings bindings = new SimpleBindings();
bindings.put("AwesomeObj", my.own.AwesomeObj.class);
scriptEngine.setBindings(bingings, ScriptContext.GLOBAL_SCOPE);

我正在开发一个框架,我想为 js 脚本提供很多类,最好不要使用字符串连接eval。目前它会抛出一个带有消息的异常: AwesomeObj 不是一个函数,这是有道理的。

4

3 回答 3

4

Nashorn 将类型与java.lang.Class实例区分开来,就像 Java 所做的那样(在 Java 语言中,my.own.AwesomeObj是类型,my.own.AwesomeObj.class而是 的实例java.lang.Class。您可以使用类型来访问静态成员,或者作为构造函数。您不能将Class对象用于那个目的。坏消息是,你不能直接获得 Nashorn 用来表示类型的对象;它是一个实例,jdk.internal.dynalink.beans.StaticClass它存在于一个受限制的包中。但是,你可以在脚本中评估它

engine.eval("Java.type('my.own.AwesomeObj')");

并将结果放入绑定中。顺便说一句,在 Nashorn 中,如果将Class对象放入 name 下的绑定AwesomeObjClass中,则可以使用综合属性.static来获取类型,例如:

var AwesomeObj = AwesomeObjClass.static;

从这个意义上说,.static一个 Class 对象是.class一个类型对象的对偶(.static显然在 Java 中不存在,其中类型没有被具体化为运行时对象)。

var stringType = Java.type("java.lang.String");
var stringClass = stringType.class
print(stringClass instanceof java.lang.Class); // true
print(stringType === stringClass.static); // true

希望这可以帮助。

于 2014-09-19T21:39:48.703 回答
1

从 Java 9 开始,您可以使用jdk.dynalink.beans.StaticClass.forClass它,因为它不再是内部的:

Bindings bindings = engine.createBindings();
bindings.put("AwesomeObj", StaticClass.forClass(my.own.AwesomeObj.class));

然后您可以使用 JS 代码中的绑定:

var awesome = new AwesomeObj();
于 2020-04-23T09:31:18.543 回答
0

在框架的顶级脚本中执行以下操作:

var AwesomeObj = Java.type("my.own.AwesomeObj");
于 2014-09-19T13:25:51.833 回答