【JDK8】Nashorn 與 Java API(一)
Nashorn 是基於 JVM 的 JavaScript 引擎,自然地,與 JVM 資源的互通性會是它的重點之一,基本上,你可以使用 JavaScript 的語法與 Nashorn 的擴充語法,存取 Java 的相關 API。 取得 Java API如果想取得 Java 標準類別,可以直接指定套件階層來存取。例如: jjs> java.lang [JavaPackage java.lang] jjs> java.lang.System [JavaClass java.lang.System] 如果是自定義類別,可以使用 jjs> Packages.cc.openhome [JavaPackage cc.openhome] jjs> Packages.cc.openhome.GetStarted [JavaClass cc.openhome.GetStarted] 不過以上兩種方式都有些缺點,使用 jjs> java.lang.Syz [JavaPackage java.lang.Syz] 為了避免這些問題,Nashorn 提供 jjs> var System = Java.type('java.lang.System') jjs> System [JavaClass java.lang.System] 使用 jjs> Java.type('int[]') [JavaClass [I] jjs> Java.type('double[]') [JavaClass [D] jjs> Java.type('java.lang.String[]') [JavaClass [Ljava.lang.String;]
jjs> var ArrayList = Java.type('java.util.ArrayList') jjs> typeof ArrayList function jjs> var lt = new ArrayList() jjs> lt.add('Justin') true jjs> lt.add('Monica') true jjs> lt.toString() [Justin, Monica] 上頭示範了呼叫實例方法的方式,如果是 Java 的靜態方法,在 JavaScript 中就是函式上的特性: jjs> var System = Java.type('java.lang.System') jjs> System.currentTimeMillis() 1401330165615 jjs> System.out.println('Hello, World') Hello, World null 如果是存取類別中的靜態類別,可以依上述的方式彈性存取,例如: jjs> Java.type('java.util.Map.Entry') [JavaClass java.util.Map$Entry] jjs> Java.type('java.util.Map$Entry') [JavaClass java.util.Map$Entry] jjs> Java.type('java.util.Map').Entry [JavaClass java.util.Map$Entry] JavaScript 基本型態與 Java APIJavaScript 的基本型態有數值、字串與布林值,因為 Nashorn 基於 JVM,因此這些型態實際上會與 Java API 有所對應,先來看實字的對應: jjs> (1).class class java.lang.Integer jjs> (11111111111).class class java.lang.Long jjs> (1111111111111111111111).class class java.lang.Double jjs> (3.14).class class java.lang.Double jjs> 'Justin'.class class java.lang.String jjs> true.class class java.lang.Boolean 可以看到,整數實字依長度不同,會分別對應至 jjs> Number(1).class class java.lang.Double JavaScript 與 Java 陣列JavaScript 中使用陣列實字建立的物件,依舊是 jjs> var arr = [1, 2, 3] jjs> arr.length 3 jjs> arr[3] = 4 4 jjs> arr 1,2,3,4 jjs> arr.constructor function Array() { [native code] } 如果想要建立 Java 中的陣列物件,可以如下: jjs> var IntArray = Java.type('int[]'); jjs> var arr = new IntArray(3) jjs> arr[0] = 1 1 jjs> arr[1] = 2 2 jjs> arr[2] = 3 3 jjs> arr[3] = 4 java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 3 上頭的陣列是具備型態約束的,也就是只能裝整數,試著在其中放些字串或浮點數值,猜猜你會看到什麼? 如果想將 JavaScript 陣列轉為 Java 陣列,可以使用 jjs> var arr = Java.to([1, 2, 3], Java.type('int[]')) jjs> arr[0] 1 jjs> arr[1] 2 jjs> arr[2] 3 jjs> arr[3] java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 3
jjs> var lt = new java.util.ArrayList(); jjs> var arr = Java.from(lt) jjs> Object.prototype.toString.call(arr) [object Array] for each 語法如果你使用 JavaScript 的 jjs> for(var i in ['a', 'b', 'c']) print(i) 0 1 2 Nashorn 擴充了一個 jjs> for each (var elem in ['a', 'b', 'c']) print(elem) a b c 這個 jjs> var map = new java.util.HashMap() jjs> map.put('k1', 10) null jjs> map.put('k2', 20) null jjs> for each(var value in map) print(value) 10 20 jjs> for each(var value in {x: 10, y: 20}) print(value) 10 20 jjs> JavaBean、List 與 MapJavaBean 物件的 Getter、Setter,可以在 Nashorn 中使用 jjs> var Date = Java.type('java.util.Date') jjs> var instant = new Date() jjs> instant.time 1401334149733 jjs> instant['time'] 1401334149733 jjs> instant.time = 1401334149733 + 1000 1401334150733 jjs> instant.time 1401334150733
jjs> var ArrayList = java.util.ArrayList jjs> var lt = new ArrayList() jjs> lt.add(1) true jjs> lt.add(2) true jjs> lt[0] 1 jjs> lt[1] 2
jjs> var HashMap = java.util.HashMap jjs> var map = new HashMap jjs> map['k1'] = 10 10 jjs> map.k2 = 20 20 jjs> map.get('k1') 10 jjs> map['k2'] 20 |