java通过scriptengine执行js脚本时,需用put()将变量绑定至engine_scope作用域,脚本中直接按js语法访问,不可用var/let重复声明以免遮蔽原值。

Java 通过 ScriptEngine 执行 JavaScript 脚本时,变量传递与脚本内使用是核心环节。关键不在于“能不能”,而在于“怎么传得准、用得稳、取得到”。JDK 6 起内置的 javax.script API 提供了简洁可靠的机制,但细节处理不当容易导致 undefined、类型转换失败或作用域丢失。
变量绑定:用 put() 把 Java 值送进 JS 作用域
JS 脚本无法直接访问 Java 变量,必须显式绑定。调用 engine.put(key, value) 后,该值在脚本中以同名全局变量形式存在。
-
基础写法:如
engine.put("userList", new String[]{"Alice", "Bob"});,脚本中可直接写users = userList; -
支持常见类型:字符串、数字、数组(
String[]或List)、Date、Map等均可自动映射;复杂对象会转为 JS 可读的包装结构 -
注意作用域:默认绑定到
ENGINE_SCOPE,即整个引擎生命周期有效;如需局部作用域,应使用createBindings()配合eval(script, bindings)
脚本内使用:按 JS 语法访问,但别依赖 var/let 声明覆盖
绑定后的变量在脚本中是“已声明”的全局变量,无需再用 var 重复定义,否则可能遮蔽原值。
-
正确示例:
for (let i = 0; i -
错误风险:
var userList = ["X"]; println(userList[0]);—— 此时输出X,而非 Java 传入的原始数组 -
动态字段访问:若传入的是
Map<string object></string>,JS 中可直接用点号或方括号,如config.timeout或config["api_url"]
结果获取:用 get() 提取脚本中计算出的变量值
脚本执行后,JS 内部生成的新变量或修改后的绑定变量,可通过 engine.get(key) 拿回 Java 端。
-
典型流程:
engine.put("base", 100); engine.eval("result = base * 1.2;"); Double r = (Double) engine.get("result"); -
类型注意:JS 数字通常返回
Double,字符串为String,布尔值为Boolean;数组可能返回NativeArray(Rhino)或Object[](Nashorn/GraalVM),建议用Arrays.asList()或流式转换 -
避免空指针:若脚本未定义该变量,
get()返回null,建议先判断再强转
实战要点:跨版本兼容与常见陷阱
JDK 版本直接影响可用引擎和行为表现,尤其要注意 Nashorn 的弃用与 GraalVM 的替代路径。
-
JDK 8–14:默认使用 Nashorn,支持
print()、println(),ES5 语法稳定 -
JDK 15+:Nashorn 移除,需引入
nashorn-core依赖,或切换至 GraalVM 的graaljs;此时推荐用标准console.log替代println -
引擎获取建议:统一用
manager.getEngineByName("JavaScript"),比"nashorn"或"js"更具移植性 -
安全提醒:勿直接执行用户输入的脚本;如需沙箱,应限制上下文、禁用
java.lang.System等敏感类,或改用 GraalVM 的隔离上下文
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











