在Graal-JS中如何从Java侧获取JS对象属性、调用JS对象方法
问题根因
- 你定义的
#width是ES标准的私有类字段,仅允许类内部访问,JS侧外部代码都无法直接读取,Java侧自然也拿不到该属性值 - 你代码中调用
map.get("size")是参数错误,你的JS对象本身不存在名为size的属性,自然返回null
解决方案
方案1:调用JS对象的公有方法(推荐)
你已经在JS类中定义了公有的getWidth() getter方法,Java侧直接调用该方法即可,推荐使用GraalVM提供的org.graalvm.polyglot.Value类处理跨语言对象,比强转Map兼容性更好:
- 引入Value类依赖
- 修改
printWidthOf方法逻辑:
import org.graalvm.polyglot.Value; public static class JavaMethods { public void printWidthOf(Object size) { System.out.println("printWidthOf started"); // 将跨语言对象转为Value类统一处理 Value jsSizeObj = Value.asValue(size); // 调用JS对象的公有getWidth方法,读取返回值转为int int width = jsSizeObj.getMember("getWidth").execute().asInt(); System.out.println("size width is " + width); } }
- 可选补充引擎配置,避免权限拦截,在main方法的bindings中新增:
bindings.put("polyglot.js.allowHostMethodLookup", true);
方案2:将属性改为公有直接读取
如果你不需要私有字段封装,可以去掉JS属性的#标识符改为公有属性,之后直接读取属性即可:
- 修改JS的Size类定义:
class Size { constructor(w, h) { // 去掉#改为公有属性 this.width = w; this.height = h; } getWidth() { return this.width; } getHeight() { return this.height; } }
- Java侧直接读取对应属性即可,两种写法都支持:
// 写法1:使用Value类 Value jsSizeObj = Value.asValue(size); int width = jsSizeObj.getMember("width").asInt(); // 写法2:强转为Map读取 Map map = (Map) size; int width = (int) map.get("width");
内容的提问来源于stack exchange,提问作者user17034580
相关产品推荐
相关产品推荐

