Java 8 Nashorn 引擎

jopen 10年前發布 | 43K 次閱讀 Java 8 Java開發

Java 8 Nashorn 腳本引擎

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

    </blockquote>

    如果你人品沒問題,你一定看到輸出了…../摳鼻

    </li>

  • 第二個栗子

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

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

    function SayHi(){

    print(“hello halu”);

    }

    SayHi();

    </blockquote>

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

    windows下面cd有個技巧可以用.在文件夾空白的位置按住shift右擊鼠標,菜單中會出現在此處打開命令窗口的選項,一般人我可不告訴他.

    </blockquote>

    命令行下輸入 jjs halu.js 就可以看到執行結果了.

    </li>

  • 第三個栗子

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

  • </ul>

    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腳本.腳本模式有兩種擴展:heredocsshell 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 }));

    </blockquote>

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

    感受

    Nashorn 真心好玩.javascript語言本身就有無限可能性,應該能做出來一些好玩的東西.下面就該考慮如何使用Nashorn做點東西了.

    PS: shell invocable 不支持 windows 真心覺得坑

    來自:http://my.oschina.net/jsmagic/blog/212455

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!