Java8 中的脚本引擎 Nashorn

顺序……熵值……无限循环的数列

Java 其实有很多脚本引擎,有可以执行 js 的,有可以执行 python 的,还有可以执行 groovy 的等等,这里只简单谈谈 Java8 中可用来执行 js 的 Nashorn 引擎。

Nashorn,发音“nass-horn”,是德国二战时一个坦克的命名,同时也是 Java8 新一代的 javascript 引擎的名字——替代了老旧,缓慢的 Rhino。Rhino 意为犀牛,由 Mozilla 开发,在 Java6 中被引入,到了8就废弃了。

两者的使用方法差不多,这里只做简要说明:

package com.binroad.test;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.List;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 * 使用脚本引擎Nashorn执行javascript代码
 */
public class Demo0 {
    public static void main(String[] args) {
        //获取脚本引擎对象
        ScriptEngineManager sem = new ScriptEngineManager();
        //这里参数可为"javascript",也可为"nashorn"
        ScriptEngine engine = sem.getEngineByName("javascript");
        System.out.println(engine.getClass());
        System.out.println("--------分割线--------");
        
        //定义变量,存储到引擎的上下文中
        engine.put("msg", "Alei is a good man!");
        String str = "var user = {name:'Alei', age:18, schools:['巴黎高师', '复旦大学']};";
        str += "print(user.name);";
        
        //执行脚本
        try {
            engine.eval(str);
            engine.eval("msg = 'Ali is a pretty woman!'");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        System.out.println(engine.get("msg"));
        System.out.println("--------分割线--------");
        
        
        try {
            //定义函数
            engine.eval("function add(a, b) {var sum = a + b; return sum;}");
            //获取调用接口
            Invocable jsInvoke = (Invocable) engine;
//          Object result = jsInvoke.invokeFunction("add", 30, 50);
            //执行函数
            Object result = jsInvoke.invokeFunction("add", new Object[] {30, 50});
            System.out.println(result);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        System.out.println("--------分割线--------");
        
        //导入其他java包,使用其他包中的java类
        String jsCode = "var list = java.util.Arrays.asList([\"巴黎高师\", \"复旦大学\", \"以色列理工学院\"])";
        try {
            engine.eval(jsCode);
            List<String> list = (List<String>) engine.get("list");
            for (String s : list) {
                System.out.println(s);
            }
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        System.out.println("--------分割线--------");
        
        //执行一个js文件(放在src下即可)
        URL url = Demo0.class.getClassLoader().getResource("a.js");
        FileReader fr = null;
        try {
            fr = new FileReader(url.getPath());
            engine.eval(fr);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

a.js 源码:

function test() {
    var a = 3;
    var b = 4;
    print("invoke js file:" + Math.sqrt(a*a + b*b));
}

test();

运行结果:

class jdk.nashorn.api.scripting.NashornScriptEngine
--------分割线--------
Alei
Ali is a pretty woman!
--------分割线--------
80.0
--------分割线--------
巴黎高师
复旦大学
以色列理工学院
--------分割线--------
invoke js file:5
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容