正如这里所解释的,解决方法是将包装的 Java 对象的原型设置为new NativeObject()
. 请注意,在链接的线程中,没有任何权威机构确认这实际上是正确的做法,因此它可能恰好适用于您的用例并破坏其他用例。
无论如何,在 Java 端设置原型的最佳位置是自定义wrapFactory
:
cx.setWrapFactory(new WrapFactory() {
@Override public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
final Object ret = super.wrap(cx, scope, obj, staticType);
if (ret instanceof Scriptable) {
final Scriptable sret = (Scriptable) ret;
if (sret.getPrototype() == null) sret.setPrototype(new NativeObject());
}
return ret;
}
});
在 JavaScript 方面,这现在可以工作了:
var test = new java.util.ArrayList();
test.x = 'a';
因此,与您发布的尝试相比,您需要颠倒对象和原型的角色。
有趣的是:现在你也可以在 JavaScript 端自由设置原型了:
test.prototype = {};
这对我来说听起来像是一个 Rhino 错误,或者至少有一点需要改进。