Nashorn 案例详解
Nashorn 是 Java 8 中引入的 JavaScript 引擎,用于在 JVM 上执行 JavaScript 代码,以下是一些实用的 Nashorn 案例:

基础执行案例
简单脚本执行
import javax.script.*;
public class BasicNashornExample {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 直接执行JavaScript代码
engine.eval("print('Hello, Nashorn!');");
// 执行带表达式的代码
Object result = engine.eval("3 + 4 * 2");
System.out.println("Result: " + result);
}
}
变量传递与返回
public class VariablePassing {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 向JavaScript传递Java对象
Bindings bindings = engine.createBindings();
bindings.put("name", "John Doe");
bindings.put("age", 25);
// 执行JavaScript并返回结果
Object result = engine.eval(
"var info = name + ' is ' + age + ' years old';" +
"info;", bindings
);
System.out.println(result);
}
}
数据转换案例
JSON 处理
import javax.script.*;
import java.util.*;
public class JsonProcessing {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 在JavaScript中处理JSON数据
engine.eval(
"var data = JSON.parse('{\"name\":\"Alice\",\"age\":30}');" +
"print('Name: ' + data.name + ', Age: ' + data.age);" +
"var jsonString = JSON.stringify({city: 'New York', population: 8000000});" +
"jsonString;"
);
// 将JavaScript对象转换为Java Map
Object jsObject = engine.eval(
"({name: 'Bob', hobbies: ['reading', 'coding']})"
);
if (jsObject instanceof Map) {
Map<?, ?> map = (Map<?, ?>) jsObject;
System.out.println("Converted to Map: " + map);
}
}
}
JavaScript 与 Java 互操作案例
调用 Java 方法
public class JavaInterop {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 在JavaScript中调用Java类
engine.eval(
"var ArrayList = Java.type('java.util.ArrayList');" +
"var list = new ArrayList();" +
"list.add('Apple');" +
"list.add('Banana');" +
"list.add('Orange');" +
"print('List size: ' + list.size());" +
"print('First element: ' + list.get(0));"
);
// 使用Java的Stream API
engine.eval(
"var IntStream = Java.type('java.util.stream.IntStream');" +
"var sum = IntStream.range(1, 11).sum();" +
"print('Sum of 1-10: ' + sum);"
);
}
}
实现 Java 接口
public class ImplementingInterface {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 在JavaScript中实现Java接口
engine.eval(
"var RunnableImpl = Java.extend(java.lang.Runnable);" +
"var task = new RunnableImpl({ run: function() {" +
" print('Task executed from JavaScript!');" +
"}});" +
"task.run();"
);
// 使用事件监听器
engine.eval(
"var ActionListener = Java.type('java.awt.event.ActionListener');" +
"var listener = new ActionListener({ actionPerformed: function(e) {" +
" print('Button clicked!');" +
"}});" +
"print('Listener created: ' + listener);"
);
}
}
性能与优化案例
编译脚本提高性能
import javax.script.*;
public class CompilationExample {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
Compilable compilable = (Compilable) engine;
// 编译脚本
String script =
"function factorial(n) {" +
" if (n <= 1) return 1;" +
" return n * factorial(n-1);" +
"}" +
"var result = factorial(10);" +
"result;";
CompiledScript compiledScript = compilable.compile(script);
// 执行编译后的脚本(更快)
long startTime = System.nanoTime();
for (int i = 0; i < 100; i++) {
Object result = compiledScript.eval();
// 使用结果...
}
long endTime = System.nanoTime();
System.out.println("编译执行时间: " + (endTime - startTime) + " ns");
}
}
实用工具案例
配置文件解析
public class ConfigParser {
public static void main(String[] args) throws ScriptException, IOException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 使用JavaScript解析JSON配置文件
String jsonConfig =
"{" +
" 'database': {'host': 'localhost', 'port': 5432}," +
" 'app': {'name': 'MyApp', 'debug': true}" +
"}";
engine.eval(
"var config = JSON.parse('" + jsonConfig.replace("'", "\"") + "');" +
"config.database.host + ':' + config.database.port;"
);
// 读取外部JS配置文件
String jsConfig = Files.readString(Paths.get("config.js"));
Object config = engine.eval(jsConfig);
System.out.println("Config: " + config);
}
}
数学计算引擎
public class MathCalculator {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 动态数学表达式计算
String expression = "Math.pow(2, 10) + Math.sqrt(144) + Math.sin(Math.PI/2)";
Object result = engine.eval(expression);
System.out.println("表达式结果: " + result);
// 创建自定义数学函数
engine.eval(
"function calculateArea(radius) {" +
" return Math.PI * radius * radius;" +
"}" +
"calculateArea(5);"
);
}
}
高级案例:完整应用程序
import javax.script.*;
import java.util.concurrent.*;
public class AdvancedNashornApp {
private ScriptEngine engine;
private ExecutorService executor;
public AdvancedNashornApp() {
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("nashorn");
executor = Executors.newFixedThreadPool(4);
}
// 异步执行JavaScript任务
public Future<Object> executeAsync(String script) {
return executor.submit(() -> {
try {
return engine.eval(script);
} catch (ScriptException e) {
throw new RuntimeException(e);
}
});
}
// 创建JavaScript API 扩展
public void setupCustomAPI() throws ScriptException {
engine.eval(
"var api = {" +
" getTime: function() { return new Date().getTime(); }," +
" log: function(message) { print('[JS LOG]: ' + message); }," +
" calculate: function(a, b) { return a + b; }" +
"};" +
"globalThis.api = api;"
);
}
public static void main(String[] args) throws Exception {
AdvancedNashornApp app = new AdvancedNashornApp();
app.setupCustomAPI();
// 异步执行任务
Future<Object> future = app.executeAsync(
"var start = api.getTime();" +
"var sum = 0;" +
"for (var i = 0; i < 1000000; i++) sum += i;" +
"'Sum: ' + sum + ', Time: ' + (api.getTime() - start) + 'ms';"
);
System.out.println(future.get());
app.executor.shutdown();
}
}
性能对比示例
public class PerformanceComparison {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 测试脚本
String script =
"function fibonacci(n) {" +
" return n < 2 ? n : fibonacci(n-1) + fibonacci(n-2);" +
"}" +
"var result = fibonacci(20);" +
"result;";
// 直接执行
long start = System.currentTimeMillis();
Object result1 = engine.eval(script);
long directTime = System.currentTimeMillis() - start;
// 编译后执行
Compilable compilable = (Compilable) engine;
CompiledScript compiled = compilable.compile(script);
start = System.currentTimeMillis();
Object result2 = compiled.eval();
long compiledTime = System.currentTimeMillis() - start;
System.out.println("直接执行: " + directTime + "ms");
System.out.println("编译执行: " + compiledTime + "ms");
// 与Java原生对比
start = System.currentTimeMillis();
int fib = fibonacci(20);
long javaTime = System.currentTimeMillis() - start;
System.out.println("Java原生: " + javaTime + "ms");
}
public static int fibonacci(int n) {
return n < 2 ? n : fibonacci(n-1) + fibonacci(n-2);
}
}
最佳实践建议
- 在脚本中使用
var而不是let/const(兼容性好) - 避免在脚本中频繁创建大型对象(内存开销)
- 使用
Compilable接口缓存常用脚本 - 利用
bindings而不是全局变量(更安全) - 合理使用异步执行(避免阻塞主线程)
- 注意类型转换(JavaScript Number → Java Double/Long)
- 使用
Java.type()访问 Java 类(比Packages更高效)
这些案例涵盖了 Nashorn 的常见用法,从基本执行到高级互操作,可根据实际需求灵活运用。