Nashorn案例

wen java案例 1

Nashorn 案例详解

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

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);
    }
}

最佳实践建议

  1. 在脚本中使用 var 而不是 let/const(兼容性好)
  2. 避免在脚本中频繁创建大型对象(内存开销)
  3. 使用 Compilable 接口缓存常用脚本
  4. 利用 bindings 而不是全局变量(更安全)
  5. 合理使用异步执行(避免阻塞主线程)
  6. 注意类型转换(JavaScript Number → Java Double/Long)
  7. 使用 Java.type() 访问 Java 类(比 Packages 更高效)

这些案例涵盖了 Nashorn 的常见用法,从基本执行到高级互操作,可根据实际需求灵活运用。

抱歉,评论功能暂时关闭!