Nashorn - JS引擎

 Nashorn是在java中高效动态执行JS代码的运行环境。

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        engine.eval("print('hello');"); // execute js from source
        File f = new File("resources/scripts.js");
        engine.eval(new FileReader(f)); // execute js from file

调用JS

  首先把需要调用的js代码保存为scripts.js:

function add(a, b) {
    return a + b;
}

var f1 = function(name) {
    print("JS: " + name);
    return "Greeting from JS";
}
var f2 = function(obj) {
    print("JS Class: " + Object.prototype.toString.call(obj));
}

    Java中调用:

        ScriptEngine engine = new ScriptEngineManager()
                .getEngineByName("nashorn");
        engine.eval("print('hello');"); // execute js from source
        File f = new File("resources/scripts.js");
        engine.eval(new FileReader(f)); // execute js from file
        Invocable invocable = (Invocable) engine;
        Object sum = invocable.invokeFunction("add", 1, 2);
        System.out.println(sum);
        invocable.invokeFunction("f2", new Date());
        invocable.invokeFunction("f2", LocalDateTime.now());            

由于js中的代码在jvm中是原生态调用,类型不会丢失。

调用Java

  Java方法必须是public。否则调用的时候找不到

    public static String greeting(String name) {
        System.out.println("From Java " + name);
        return "From Java";
    }

    public static void getCls(Object obj) {
        System.out.println(obj.getClass());
    }

     ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
     File f = new File("resources/scripts.js");
     engine.eval(new FileReader(f)); // execute js from file

 

  JS代码:

var cls = Java.type("nashorn.NashornTest");
print(cls.greeting('Zhijie'));

    原始JS类型可以转换成适当的Java包装类。原生JS对象表示成内部适配类。

  

cls.getCls(123);
//class java.lang.Integer

cls.getCls(49.99);
//class java.lang.Double

cls.getCls(true);
//class java.lang.Boolean

cls.getCls("hi there")
//class java.lang.String

cls.getCls(new Number(23));
//class jdk.nashorn.internal.objects.NativeNumber

cls.getCls(new Date());
//class jdk.nashorn.internal.objects.NativeDate

cls.getCls(new RegExp());
//class jdk.nashorn.internal.objects.NativeRegExp

cls.getCls({foo: 'bar'});
//class jdk.nashorn.internal.scripts.JO4

ScriptObjectMirror

jdk.nashorn.api.scripting.ScriptObjectMirror是JS对象在Java中的映射。这个类实现了Map接口。

    
    public static void f(ScriptObjectMirror mirror) {
        System.out.println(mirror.getClassName() + ": " +
            Arrays.toString(mirror.getOwnKeys(true)));
    }
    
    public static void callMethodOfJSObject(ScriptObjectMirror person) {
        System.out.println("Full Name is: " + person.callMember("getFullName"));
    }
cls.f({a:'a',b:'b'});

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.getFullName = function() {
        return this.firstName + " " + this.lastName;
    }
}

var person1 = new Person("Zhijie", "Liu");
cls.callMethodOfJSObject(person1);

 Nashorn扩展了ECMAScript 5:

  • Typed Arrays

  • Collections and For Each

  • Lambda expressions and Streams

  • Extending classes

  • Parameter overloading

  • Java Beans

  • Function Literals

  • Binding properties

  • Trimming strings

  • Whereis

  • Import Scopes

  • Convert arrays

  • Calling Super

  • Loading scripts

可以进一步阅读http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/

posted @ 2015-09-21 09:22  码农大刘  阅读(3715)  评论(0编辑  收藏  举报