java8 Nashorn

曾經和朋友開玩笑說、java最后的發展就剩下java虛擬機了、的確,java虛擬機從誕生起到現在已經經過大神的優化、已經變得相當成熟穩定、隨著java虛擬機的發展、越來越多的基于java虛擬機的語言被應用到軟件開發當中。
同樣許多有很長歷史的程序設計語言也出現了基于java虛擬機的實現的版本.Nashorn便是javascript版本的基于java虛擬機的實現.今天我們著重講解java8引入的Nashorn引擎的使用.

接下來我們介紹java中nashorn的具體使用。

  1. 在java代碼中執行JavaScript腳本,首先需要創建一個nashorn腳本引擎對象
    傳遞JavaScript字符串代碼給eval函數執行。
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello World!');");
  1. 傳遞一個FileReader對象指向的腳本文件
engine.eval(new FileReader(scriptFileName));

(function(){
    print('hello world');
})();

目前nashorn支持EcmaScript5.1但是未來版本會支持EcmaScript6
nashorn提供了許多EcmaScript語言和API層面的擴展

如何在java和JavaScript之間進行通訊

在java代碼中調用JavaScript函數Function,Nashorn支持在你的java代碼中直接調用腳本文件定義的函數,你可以傳遞java對象給JavaScript方法并且返回給調用者.

首先為了調用JavaScript中方法,我們必須將引擎對象轉為化Invocable接口
Invocable提供了invokeFunction方法通過名稱調用JavaScript方法

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader(scriptFile));
        Invocable invocable = (Invocable) engine;
        Object result = invocable.invokeFunction("fun1", "Peter Parker");//Hi there from Javascript, Peter Parker
        System.out.println(result);//Hi there from Javascript, Peter Parker

其中scriptFile的內容為
var fun1 = function (name) {
    print('Hi there from Javascript, ' + name);
    return "greetings from javascript";
};
var fun2 = function (object) {
    print("JS Class Definition: " + Object.prototype.toString.call(object));
};

invocable.invokeFunction("fun2", new Date());// [object java.util.Date]
invocable.invokeFunction("fun2", LocalDateTime.now());// [object java.time.LocalDateTime]
invocable.invokeFunction("fun2", new Person());// JS Class Definition: [object com.test.java8.Person]

從以上輸出結果可以看出JavaScript腳本文件中完整的保存著java參數類型,究其原因、是因為不管是java還是narshorn都是在jvm虛擬機上執行的、底層都是java虛擬機進行解釋執行的.

在JavaScript中調用java方法,注意:在JavaScript中只能調用public方法

假設script中有fun4
var fun4 = function () {
    var MyJavaClass =Java.type('$(javaClasName)');
    MyJavaClass.fun2(123);
}

其中$(javaClasName)為java的類權限命名
類javaClasName中存在fun2方法

然而nashorn是怎么樣處理java類型和JavaScript類型之間的轉換呢?
我們看幾個例子

假設JavaScript中fun5
var fun5 = function(){

// class java.lang.Integer

    MyJavaClass.fun2(49.99);
// class java.lang.Double

    MyJavaClass.fun2(true);
// class java.lang.Boolean

    MyJavaClass.fun2("hi there")
// class java.lang.String

    MyJavaClass.fun2(new Number(23));
// class jdk.nashorn.internal.objects.NativeNumber

    MyJavaClass.fun2(new Date());
// class jdk.nashorn.internal.objects.NativeDate

    MyJavaClass.fun2(new RegExp());
// class jdk.nashorn.internal.objects.NativeRegExp

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

}

在java中調用javascript的fun4方法
invocable.invokeFunction("fun4");
從輸出結果我們可以看出:
1. 基本類型的javascript類型轉換成Java中對應的基本類型
2. 引用類型或者對象類型轉換成java中的內部包裝類型ScriptObjectMirror

那么ScriptObjectMirror這個是什么呢?
ScriptObjectMirror可以作為JavaScript對象和java對象的橋梁
當我們在JavaScript中調用java代碼的時候、傳遞給java代碼JavaScript對象的時候我們可以利用ScriptObjectMirror對象作為橋梁;
我們看個例子:

假設script中存在構造器對象
function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.getFullName = function() {
        return this.firstName + " " + this.lastName;
    }
}

 var person1 = new Person("Peter", "Parker");
 MyJavaClass.fun4(person1);

在Java中fun4為:
public static void fun4(ScriptObjectMirror person) {
        System.out.println("Full Name is: " + person.callMember("getFullName"));
    }
從輸出結果我們可以看出JavaScript中的對象類型在java中被轉化為ScriptObjectMirror對象、并且從ScriptObjectMirror對象中可以獲取到JavaScript對象中的方法和屬性信息.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容