Java 8 Nashorn 脚本引擎

开发 后端
java8 终于来了.函数式接口,lambda表达式期待很久了.新的武器在手,应该可以玩出新花样. 前两天无意中发现java8 中还带了另外一个有意思的东西. Nashorn 一个javascript引擎. 这等好玩的东西不把玩一下实在是浪费了.所以直接找到了oracle官方的介绍文档.说实话,文档真给力啊.

java8 终于来了.函数式接口,lambda表达式期待很久了.新的武器在手,应该可以玩出新花样.

前两天无意中发现java8 中还带了另外一个有意思的东西.

Nashorn 一个javascript引擎.

这等好玩的东西不把玩一下实在是浪费了.所以直接找到了oracle官方的介绍文档.说实话,文档真给力啊.

这篇文章是我一边看Oracle官方文档,一边敲代码试验,一边写的,不算是翻译的文档,算是中文版总结文档吧。呵呵。

原文地址:Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM

java7以前,JDK内置了一个基于Mozilla Rhino的javascript脚本引擎。在java8里面,基于JSR292和invokedynamic重新提供了一个新的javascript引擎-Oracle Nashorn。它更符合ECMA标准的javascript规范,而且基于invokedynamic调用拥有更好的性能。

文章使用的是***的JDK8.所以想用要先装一下。

★ ***个栗子

***个程序一定是HelloWorld.而且是命令行下面的实现.因此.打开一个命令行吧.

如果你的命令行配好了,输入 jjs 回车

就可以看到Nashrn的命令行了.

print("hello halu");

如果你人品没问题,你一定看到输出了…../抠鼻

★ 第二个栗子

命令行下面可以用了,那么抓紧试试用js文件吧.

把下面的代码保存在一个文件里面,我的文件名是halu.js

function SayHi(){

print(“hello halu”);

}

SayHi();

然后打开命令行,cd到文件所在的目录.

windows下面cd有个技巧可以用.在文件夹空白的位置按住shift右击鼠标,菜单中会出现在此处打开命令窗口的选项,一般人我可不告诉他.

命令行下输入 jjs halu.js 就可以看到执行结果了.

 第三个栗子

要知道,这可是java8 环境.看下面的例子吧.

var data = [1,2,3,4,5,6,7,8,9,10];

var filtered = data.filter(function(i){

return i%2 == 0;

},0);

print(filtered);

var sumOfFilterd = filtered.reduce(function (acc,next){

return acc + next;

},0);

print(sumOfFilterd);

看一下执行结果吧.这个例子里面信息量可是巨大的.

Nashorn 只是使用遵从 ECMA 规范的javascript语言,在网页上常用的对象Nashorn里面并没有.比如说console,window等对象.

★ 第四个栗子

命令行执行以下 jjs -help,在帮助中可以看到.

  • jjs可以运行javaFX程序脚本

  • 可以使用javascript严格模式.

  • 可以指定额外的classpath.

  • 一个有趣的脚本模式

脚本模式很有趣,你可以使用jjs运行使用javascript编写的系统脚本.类似python,ruby,bash脚本.脚本模式有两种扩展:heredocs和shell invocations.

var data = { 
foo:“bar”, 
time: new Date() 
};

print(“< So…foo = ${data.foo} and the current time is ${data.time} EOF”);

使用 jjs -scripting halu.js 执行该脚本.

heredocs 是一种简单的多行文本,使用类似bash的语法.使用 < 符号开始后面跟一个特殊标记.字符串中可以使用 ${} 表达式(类似EL表达式).需要注意的是,如果使用单引号引起来的字符串,内部的标示是不会被替换的.

★ 第五个栗子

Shell invocations 是允许调用命令行程序.

var lines =`ls`;

print(lines);

这样就可以执行shell命令了.当然windows下面失败….

*注意符号是 ` [波浪线那个键],不是 ' [单引号] * ,我找了好久才发现.

★ 第六个栗子

下面我们来写一个 java 程序

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

public class halu{

public static void main(String[] args) throws Throwable{

ScriptEngineManager engineManager = new ScriptEngineManager();

ScriptEngine engine = engineManager.getEngineByName(“nashorn”);

engine.eval(“function sum(a,b){return a+b;}“);

System.out.println(engine.eval(“sum(1,2);“));

}

}

这段代码很简单,使用ScriptEngineManager 获得一个 ScriptEngine.然后通过eval函数执行字符串脚本.

Invocable invocable = (Invocable) engine;

System.out.println(invocable.invokeFunction(“sum”,1,3));

engine 也可以使用invocable接口调用脚本内的函数.

增加一个 Adder.java 的接口

public interface Adder{

int sum(int a, int b);

}

halu类里面

Adder adderaa = invocable.getInterface(Adder.class);

System.out.println(““+ adderaa.sum(2,3));

这样可以将javascript的类映射到java的接口上.个人感觉这是个很强大的功能.

读取脚本文件执行.使用 java.io.FileReader;

engine.eval(new FileReader(“halu.js”));

★ 第七个例子

我们来使用javascript调用java

print(java.lang.System.currentTimeMillis());

var file = new java.io.File(“halu.js”);

print(file.getAbsolutePath());

print(file.absolutePath);

使用 jjs 命令执行哦~

集合的使用

var stack =

new java.util.LinkedList();

[1, 2, 3, 4].forEach(function(item) {

stack.push(item);

});

print(stack);

print(stack.getClass());

★ 第八个例子

javascript实现java接口

var iterator = new java.util.Iterator({

i: 0,

hasNext: function() {

return this.i < 10;

},

next: function() {

return this.i++;

}

});

print(iterator instanceof Java.type(“java.util.Iterator”));

while (iterator.hasNext()) {

print(“-> " + iterator.next());

}

★ 第九个例子

javascript 实现多个接口

var ObjectType = Java.type(“java.lang.Object”);

var Comparable = Java.type(“java.lang.Comparable”);

var Serializable = Java.type(“java.io.Serializable”);

var MyExtender = Java.extend(

ObjectType, Comparable, Serializable);

var instance = new MyExtender({

someInt: 0,

compareTo: function(other) {

var value = other[“someInt”];

if (value === undefined) {

return 1;

}

if (this.someInt < value) {

return -1;

} else if (this.someInt == value) {

return 0;

} else {

return 1;

}

}

});

print(instance instanceof Comparable);

print(instance instanceof Serializable);

print(instance.compareTo({ someInt: 10 }));

print(instance.compareTo({ someInt: 0 }));

print(instance.compareTo({ someInt: -10 }));

终于完了….累死我了….

感受

Nashorn 真心好玩。javascript语言本身就有无限可能性,应该能做出来一些好玩的东西.下面就该考虑如何使用Nashorn做点东西了。

原文链接:http://my.oschina.net/jsmagic/blog/212455

 

责任编辑:林师授 来源: oschina
相关推荐

2016-12-15 14:13:16

Java 8Nashorn脚本

2014-07-14 11:34:53

Java 8Nashorn

2009-04-04 09:42:53

IE8JScript浏览器

2014-07-15 14:48:26

Java8

2014-03-19 11:04:14

Java 8Java8特性

2011-08-29 15:10:19

JAVALua 脚本

2009-12-28 10:16:48

Groovy 1.7

2010-09-30 11:16:53

J2ME Snake脚

2018-08-28 16:02:59

LinuxShellBash

2019-10-09 16:08:21

PythonPython教程Python 开发

2010-10-09 15:00:22

SnakeJ2ME

2016-09-26 14:16:18

shell脚本bash

2018-06-06 09:32:39

编程语言Python搜索引擎

2009-07-07 09:24:24

2013-12-06 10:12:49

Android游戏引擎libgdx教程

2022-10-24 09:11:05

TypeScriptV8

2012-12-24 08:51:23

iOSUnity3D

2024-12-26 00:14:45

C#脚本开源

2012-02-03 15:13:27

JavaScript

2020-06-19 12:59:33

动态脚本Java
点赞
收藏

51CTO技术栈公众号