为了创建 Java 数组对象,首先需要获取 Java 数组类型对象并进行初始化。JavaScript 访问数组元素的语法以及 length 属性都跟 Java 一样,如下列代码所示:
var StringArray = Java.type("java.lang.String[]"); var a = new StringArray(5); // Set the value of the first element a[0] = "Scripting is great!"; // Print the length of the array print(a.length); // Print the value of the first element print(a[0]);
给定一个 JavaScript 数组 我们还可以用 Java.to() 方法将它转成 Java 数组。我们需要将 JavaScript 数组作为参数传给该方法,并指定要返回的数组类型,可以是一个字符串,或者是类型对象。我们也可以忽略类型对象参数来返回 Object[] 数组。转换操作是根据 ECMAScript 转换规则进行的。下面代码展示如何通过不同的 Java.to() 的参数将 JavaScript 数组变成 Java 数组:
// 创建一个 JavaScript 数组 var anArray = [1, "13", false]; // 将数组转换成 java 的 int[] 数组 var javaIntArray = Java.to(anArray, "int[]"); print(javaIntArray[0]); // prints the number 1 print(javaIntArray[1]); // prints the number 13 print(javaIntArray[2]); // prints the number 0 // 将 JavaScript 数组转换成 Java 的 String[] 数组 var javaStringArray = Java.to(anArray, Java.type("java.lang.String[]")); print(javaStringArray[0]); // prints the string "1" print(javaStringArray[1]); // prints the string "13" print(javaStringArray[2]); // prints the string "false" // 将 JavaScript 数组转换成 Java 的 Object[] 数组 var javaObjectArray = Java.to(anArray); print(javaObjectArray[0]); // prints the number 1 print(javaObjectArray[1]); // prints the string "13" print(javaObjectArray[2]); // prints the boolean value "false"
你可以使用 Java.from() 方法来将一个 Java 数组转成 JavaScript 数组。
下面代码演示如何将一个包含当前目录下文件列表的数组转成 JavaScript 数组:
// Get the Java File type object var File = Java.type("java.io.File"); // Create a Java array of File objects var listCurDir = new File(".").listFiles(); // Convert the Java array to a JavaScript array var jsList = Java.from(listCurDir); // Print the JavaScript array print(jsList);
注意:
大多数情况下,你可以在脚本中使用 Java 对象而无需转换成 JavaScript 对象。
4、实现 Java 接口
在 JavaScript 实现 Java 接口的语法与在 Java 总定义匿名类的方法类似。我们只需要实例化接口并用 JavaScript 函数实现其方法即可。
下面代码演示如何实现 Runnable 接口:
// Create an object that implements the Runnable interface by implementing // the run() method as a JavaScript function var r = new java.lang.Runnable() { run: function() { print("running...\n"); } }; // The r variable can be passed to Java methods that expect an object implementing // the java.lang.Runnable interface var th = new java.lang.Thread(r); th.start(); th.join();
如果一个方法希望一个对象,这个对象实现了只有一个方法的接口,你可以传递一个脚本函数给这个方法,而不是传递对象。例如,在上面的例子中 Thread() 构造函数要求一个实现了 Runnable 接口的对象作为参数。我们可以利用自动转换的优势传递一个脚本函数给 Thread() 构造器。
下面的例子展示如何创建一个 Thread 对象而无需实现 Runnable 接口:
// Define a JavaScript function function func() { print("I am func!"); }; // Pass the JavaScript function instead of an object that implements // the java.lang.Runnable interface var th = new java.lang.Thread(func); th.start(); th.join();
你可以通过传递相关类型对象给 Java.extend() 函数来实现多个接口。
5、扩展抽象 Java 类
你可以实例化一个匿名的抽象类的子类,只需要给构造函数传递一个 JavaScript 对象,对象中包含了一些属性对应了抽象类方法实现的值。如果一个方法是重载的,JavaScript 函数将会提供所有方法变种的实现。下面例子显示如何初始化抽象类 TimerTask 的子类:
var TimerTask = Java.type("java.util.TimerTask"); var task = new TimerTask({ run: function() { print("Hello World!") } });
除了调用构造函数并传递参数,我们还可以在 new 表达式后面直接提供参数。
下面的例子显示该语法的使用方法(类似 Java 匿名内部类的定义),这比上面的例子要简单一些:
var task = new TimerTask { run: function() { print("Hello World!") } };
如果抽象类包含单个抽象方法(SAM 类型),那么我们就无需传递 JavaScript 对象给构造函数,我们可以传递一个实现了该方法的函数接口。下面的例子显示如何使用 SAM 类型来简化代码:
var task = new TimerTask(function() { print("Hello World!") });
不管你选择哪种语法,如果你需要调用一个包含参数的构造函数,你可以在实现对象和函数中指定参数。