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/