Java 8 Nashorn 引擎

Java 8 Nashorn 腳本引擎

java8 終於來了.函數式接口,lambda表達式期待好久了.新的武器在手,應該能夠玩出新花樣.javascript

前兩天無心中發現java8 中還帶了另一個有意思的東西.html

Nashorn 一個javascript引擎.java

這等好玩的東西不把玩一下實在是浪費了.因此直接找到了oracle官方的介紹文檔.說實話,文檔真給力啊.python

這篇文章是我一邊看Oracle官方文檔,一邊敲代碼試驗,一邊寫的,不算是翻譯的文檔,算是中文版總結文檔吧.呵呵.shell

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

java7之前,JDK內置了一個基於Mozilla Rhino的javascript腳本引擎.在java8裏面,基於JSR292和invokedynamic從新提供了一個新的javascript引擎-Oracle Nashorn.它更符合ECMA標準的javascript規範,並且基於invokedynamic調用擁有更好的性能.ruby

文章使用的是最新的JDK8.因此想用要先裝一下.bash

  • 第一個栗子oracle

    第一個程序必定是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腳本.腳本模式有兩種擴展: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 }));

終於完了....累死我了....

感覺

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

#PS: shell invocable 不支持 windows 真心以爲坑.....誰要是有辦法請留言給我.

相關文章
相關標籤/搜索