在JavaScript中調(diào)用Java類(lèi)和接口的方法
前言
本文中所有的代碼使用 JavaScript 編寫(xiě),但你也可以用其他兼容 JSR 223 的腳本語(yǔ)言。這些例子可作為腳本文件也可以在交互式 Shell 中一次運(yùn)行一個(gè)語(yǔ)句的方式來(lái)運(yùn)行。在 JavaScript 中訪(fǎng)問(wèn)對(duì)象的屬性和方法的語(yǔ)法與 Java 語(yǔ)言相同。
本文包含如下幾部分:
1、訪(fǎng)問(wèn) Java 類(lèi)
為了在 JavaScript 中訪(fǎng)問(wèn)原生類(lèi)型或者引用 Java 類(lèi)型,可以調(diào)用 Java.type()
函數(shù),該函數(shù)根據(jù)傳入的完整類(lèi)名返回對(duì)應(yīng)對(duì)象的類(lèi)型。下面代碼顯示如何獲取不同的對(duì)象類(lèi)型:
var ArrayList = Java.type("java.util.ArrayList"); var intType = Java.type("int"); var StringArrayType = Java.type("java.lang.String[]"); var int2DArrayType = Java.type("int[][]");
在 JavaScript 中使用 Java.type()
函數(shù)返回的類(lèi)型對(duì)象的方法跟在 Java 的類(lèi)似。
例如你可以使用如下方法來(lái)實(shí)例化一個(gè)類(lèi):
var anArrayList = new Java.type("java.util.ArrayList");
Java 類(lèi)型對(duì)象可用來(lái)實(shí)例化 Java 對(duì)象。下面的代碼顯示如何使用默認(rèn)的構(gòu)造函數(shù)實(shí)例化一個(gè)新對(duì)象以及調(diào)用包含參數(shù)的構(gòu)造函數(shù):
var ArrayList = Java.type("java.util.ArrayList"); var defaultSizeArrayList = new ArrayList; var customSizeArrayList = new ArrayList(16);
你可以使用 Java.type()
方法來(lái)獲取對(duì)象類(lèi)型,可以使用如下方法來(lái)訪(fǎng)問(wèn)靜態(tài)屬性以及方法:
var File = Java.type("java.io.File"); File.createTempFile("nashorn", ".tmp");
如果要訪(fǎng)問(wèn)內(nèi)部靜態(tài)類(lèi),可以傳遞美元符號(hào) $ 給 Java.type()
方法。
下面代碼顯示如何返回 java.awt.geom.Arc2D
的 Float
內(nèi)部類(lèi):
var Float = Java.type("java.awt.geom.Arc2D$Float");
如果你已經(jīng)有一個(gè)外部類(lèi)類(lèi)型對(duì)象,那么你可以像訪(fǎng)問(wèn)屬性一樣訪(fǎng)問(wèn)其內(nèi)部類(lèi),如下所示:
var Arc2D = Java.type("java.awt.geom.Arc2D") var Float = Arc2D.Float
由于是非靜態(tài)內(nèi)部類(lèi),必須傳遞的是外部類(lèi)實(shí)例作為參數(shù)給構(gòu)造函數(shù)。
雖然在 JavaScript 中使用類(lèi)型對(duì)象跟在 Java 中類(lèi)似,但其與 java.lang.Class
對(duì)象還是有些區(qū)別的,這個(gè)區(qū)別就是 getClass()
方法的返回值。你可以使用 class
和 static
屬性來(lái)獲取這個(gè)信息。
下面代碼顯示二者的區(qū)別:
var ArrayList = Java.type("java.util.ArrayList"); var a = new ArrayList; // All of the following are true: print("Type acts as target of instanceof: " + (a instanceof ArrayList)); print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass())); print("Type is not the same as instance's getClass(): " + (a.getClass() !== ArrayList)); print("Type's `class` property is the same as instance's getClass(): " + (a.getClass() === ArrayList.class)); print("Type is the same as the `static` property of the instance's getClass(): " + (a.getClass().static === ArrayList));
在語(yǔ)法和語(yǔ)義上,JavaScript 在編譯時(shí)類(lèi)表達(dá)式和運(yùn)行時(shí)對(duì)象都和 Java 語(yǔ)義類(lèi)似。不過(guò)在 Java 中 Class 對(duì)象是沒(méi)有名為 static 這樣的屬性,因?yàn)榫幾g時(shí)的類(lèi)表達(dá)式不作為對(duì)象。
2、導(dǎo)入 Java 包和類(lèi)
為了根據(jù)其簡(jiǎn)單的名稱(chēng)來(lái)訪(fǎng)問(wèn) Java 類(lèi),我們可以使用 importPackage()
和 importClass()
函數(shù)來(lái)導(dǎo)入 Java 的包和類(lèi)。這些函數(shù)存在于兼容性腳本文件 (mozilla_compat.js) 中。
下面例子展示如何使用 importPackage()
和 importClass()
函數(shù):
// Load compatibility script load("nashorn:mozilla_compat.js"); // Import the java.awt package importPackage(java.awt); // Import the java.awt.Frame class importClass(java.awt.Frame); // Create a new Frame object var frame = new java.awt.Frame("hello"); // Call the setVisible() method frame.setVisible(true); // Access a JavaBean property print(frame.title);
可以通過(guò) Packages 全局變量來(lái)訪(fǎng)問(wèn) Java 包,例如Packages.java.util.Vector
或者 Packages.javax.swing.JFrame
。但標(biāo)準(zhǔn)的 Java SE 包有更簡(jiǎn)單的訪(fǎng)問(wèn)方式,如: java 對(duì)應(yīng) Packages.java, javax 對(duì)應(yīng) Packages.javax, 以及 org 對(duì)應(yīng) Packages.org。
java.lang 包默認(rèn)不需要導(dǎo)入,因?yàn)檫@會(huì)和 Object
、Boolean
、Math
等其他 JavaScript 內(nèi)建的對(duì)象在命名上沖突。此外,導(dǎo)入任何 Java 包和類(lèi)也可能導(dǎo)致 JavaScript 全局作用域下的變量名沖突。為了避免沖突,我們定義了一個(gè) JavaImporter 對(duì)象,并通過(guò) with
語(yǔ)句來(lái)限制導(dǎo)入的 Java 包和類(lèi)的作用域,如下列代碼所示:
// Create a JavaImporter object with specified packages and classes to import var Gui = new JavaImporter(java.awt, javax.swing); // Pass the JavaImporter object to the "with" statement and access the classes // from the imported packages by their simple names within the statement's body with (Gui) { var awtframe = new Frame("AWT Frame"); var jframe = new JFrame("Swing JFrame"); };
3、使用 Java 數(shù)組
為了創(chuàng)建 Java 數(shù)組對(duì)象,首先需要獲取 Java 數(shù)組類(lèi)型對(duì)象并進(jìn)行初始化。JavaScript 訪(fǎng)問(wèn)數(shù)組元素的語(yǔ)法以及 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]);
給定一個(gè) JavaScript 數(shù)組 我們還可以用 Java.to()
方法將它轉(zhuǎn)成 Java 數(shù)組。我們需要將 JavaScript 數(shù)組作為參數(shù)傳給該方法,并指定要返回的數(shù)組類(lèi)型,可以是一個(gè)字符串,或者是類(lèi)型對(duì)象。我們也可以忽略類(lèi)型對(duì)象參數(shù)來(lái)返回 Object[] 數(shù)組。轉(zhuǎn)換操作是根據(jù) ECMAScript 轉(zhuǎn)換規(guī)則進(jìn)行的。下面代碼展示如何通過(guò)不同的 Java.to()
的參數(shù)將 JavaScript 數(shù)組變成 Java 數(shù)組:
// 創(chuàng)建一個(gè) JavaScript 數(shù)組 var anArray = [1, "13", false]; // 將數(shù)組轉(zhuǎn)換成 java 的 int[] 數(shù)組 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 數(shù)組轉(zhuǎn)換成 Java 的 String[] 數(shù)組 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 數(shù)組轉(zhuǎn)換成 Java 的 Object[] 數(shù)組 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()
方法來(lái)將一個(gè) Java 數(shù)組轉(zhuǎn)成 JavaScript 數(shù)組。
下面代碼演示如何將一個(gè)包含當(dāng)前目錄下文件列表的數(shù)組轉(zhuǎn)成 JavaScript 數(shù)組:
// 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);
注意:
大多數(shù)情況下,你可以在腳本中使用 Java 對(duì)象而無(wú)需轉(zhuǎn)換成 JavaScript 對(duì)象。
4、實(shí)現(xiàn) Java 接口
在 JavaScript 實(shí)現(xiàn) Java 接口的語(yǔ)法與在 Java 總定義匿名類(lèi)的方法類(lèi)似。我們只需要實(shí)例化接口并用 JavaScript 函數(shù)實(shí)現(xiàn)其方法即可。
下面代碼演示如何實(shí)現(xiàn) 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();
如果一個(gè)方法希望一個(gè)對(duì)象,這個(gè)對(duì)象實(shí)現(xiàn)了只有一個(gè)方法的接口,你可以傳遞一個(gè)腳本函數(shù)給這個(gè)方法,而不是傳遞對(duì)象。例如,在上面的例子中 Thread()
構(gòu)造函數(shù)要求一個(gè)實(shí)現(xiàn)了 Runnable
接口的對(duì)象作為參數(shù)。我們可以利用自動(dòng)轉(zhuǎn)換的優(yōu)勢(shì)傳遞一個(gè)腳本函數(shù)給 Thread()
構(gòu)造器。
下面的例子展示如何創(chuàng)建一個(gè) Thread
對(duì)象而無(wú)需實(shí)現(xiàn) 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();
你可以通過(guò)傳遞相關(guān)類(lèi)型對(duì)象給 Java.extend()
函數(shù)來(lái)實(shí)現(xiàn)多個(gè)接口。
5、擴(kuò)展抽象 Java 類(lèi)
你可以實(shí)例化一個(gè)匿名的抽象類(lèi)的子類(lèi),只需要給構(gòu)造函數(shù)傳遞一個(gè) JavaScript 對(duì)象,對(duì)象中包含了一些屬性對(duì)應(yīng)了抽象類(lèi)方法實(shí)現(xiàn)的值。如果一個(gè)方法是重載的,JavaScript 函數(shù)將會(huì)提供所有方法變種的實(shí)現(xiàn)。下面例子顯示如何初始化抽象類(lèi) TimerTask 的子類(lèi):
var TimerTask = Java.type("java.util.TimerTask"); var task = new TimerTask({ run: function() { print("Hello World!") } });
除了調(diào)用構(gòu)造函數(shù)并傳遞參數(shù),我們還可以在 new
表達(dá)式后面直接提供參數(shù)。
下面的例子顯示該語(yǔ)法的使用方法(類(lèi)似 Java 匿名內(nèi)部類(lèi)的定義),這比上面的例子要簡(jiǎn)單一些:
var task = new TimerTask { run: function() { print("Hello World!") } };
如果抽象類(lèi)包含單個(gè)抽象方法(SAM 類(lèi)型),那么我們就無(wú)需傳遞 JavaScript 對(duì)象給構(gòu)造函數(shù),我們可以傳遞一個(gè)實(shí)現(xiàn)了該方法的函數(shù)接口。下面的例子顯示如何使用 SAM 類(lèi)型來(lái)簡(jiǎn)化代碼:
var task = new TimerTask(function() { print("Hello World!") });
不管你選擇哪種語(yǔ)法,如果你需要調(diào)用一個(gè)包含參數(shù)的構(gòu)造函數(shù),你可以在實(shí)現(xiàn)對(duì)象和函數(shù)中指定參數(shù)。
如果你想要調(diào)用一個(gè)要求 SAM 類(lèi)型參數(shù)的 Java 方法,你可以傳遞一個(gè) JavaScript 函數(shù)給該方法。Nashorn 將根據(jù)方法需要來(lái)實(shí)例化一個(gè)子類(lèi)并使用這個(gè)函數(shù)去實(shí)現(xiàn)唯一的抽象方法。
下面的代碼顯示如何調(diào)用 Timer.schedule()
方法,該方法要求一個(gè) TimerTask 對(duì)象作為參數(shù):
var Timer = Java.type("java.util.Timer"); Timer.schedule(function() { print("Hello World!") });
注意:
前面的語(yǔ)法假設(shè)所要求的 SAM 類(lèi)型是一個(gè)接口或者包含一個(gè)默認(rèn)構(gòu)造函數(shù),Nashorn 用它來(lái)初始化一個(gè)子類(lèi)。這里是無(wú)法使用不包含默認(rèn)構(gòu)造函數(shù)的類(lèi)的。
6、擴(kuò)展具體 Java 類(lèi)
為了避免混淆,擴(kuò)展抽象類(lèi)的語(yǔ)法不能用于擴(kuò)展具體類(lèi)。因?yàn)橐粋€(gè)具體類(lèi)是可以被實(shí)例化的,這樣的語(yǔ)法會(huì)被解析成試圖創(chuàng)建一個(gè)新的類(lèi)實(shí)例并傳遞構(gòu)造函數(shù)所需類(lèi)的對(duì)象(如果預(yù)期的對(duì)象類(lèi)型是一個(gè)接口)。為了演示這個(gè)問(wèn)題,請(qǐng)看看下面的示例代碼:
var t = new java.lang.Thread({ run: function() { print("Thread running!") } });
這行代碼被解析為擴(kuò)展了 Thread
類(lèi)并實(shí)現(xiàn)了 run()
方法,而 Thread
類(lèi)的實(shí)例化是通過(guò)傳遞給其構(gòu)造函數(shù)一個(gè)實(shí)現(xiàn)了 Runnable 接口的對(duì)象。
為了擴(kuò)展一個(gè)具體類(lèi),傳遞其類(lèi)型對(duì)象給 Java.extend()
函數(shù),然后返回其子類(lèi)的類(lèi)型對(duì)象。緊接著就可以使用這個(gè)子類(lèi)的類(lèi)型對(duì)象來(lái)創(chuàng)建實(shí)例并提供額外的方法實(shí)現(xiàn)。
下面的代碼將向你展示如何擴(kuò)展 Thread
類(lèi)并實(shí)現(xiàn) run()
方法:
var Thread = Java.type("java.lang.Thread"); var threadExtender = Java.extend(Thread); var t = new threadExtender() { run: function() { print("Thread running!") }};
Java.extend()
函數(shù)可以獲取多個(gè)類(lèi)型對(duì)象的列表。你可以指定不超過(guò)一個(gè) Java 的類(lèi)型對(duì)象,也可以指定跟 Java接口一樣多的類(lèi)型對(duì)象數(shù)量。返回的類(lèi)型對(duì)象擴(kuò)展了指定的類(lèi)(或者是 java.lang.Object
,如果沒(méi)有指定類(lèi)型對(duì)象的話(huà)),這個(gè)類(lèi)實(shí)現(xiàn)了所有的接口。類(lèi)的類(lèi)型對(duì)象無(wú)需在列表中排在首位。
7、訪(fǎng)問(wèn)超類(lèi)(父類(lèi))的方法
想要訪(fǎng)問(wèn)父類(lèi)的方法可以使用 Java .super()
函數(shù)。
下面的例子中顯示如何擴(kuò)展 java.lang.Exception
類(lèi),并訪(fǎng)問(wèn)父類(lèi)的方法。
Example 3-1 訪(fǎng)問(wèn)父類(lèi)的方法 (super.js) var Exception = Java.type("java.lang.Exception"); var ExceptionAdapter = Java.extend(Exception); var exception = new ExceptionAdapter("My Exception Message") { getMessage: function() { var _super_ = Java.super(exception); return _super_.getMessage().toUpperCase(); } } try { throw exception; } catch (ex) { print(exception); }
如果你運(yùn)行上面代碼將會(huì)打印如下內(nèi)容:
jdk.nashorn.javaadapters.java.lang.Exception: MY EXCEPTION MESSAGE
8、綁定實(shí)現(xiàn)到類(lèi)
前面的部分我們描述了如何擴(kuò)展 Java 類(lèi)以及使用一個(gè)額外的 JavaScript 對(duì)象參數(shù)來(lái)實(shí)現(xiàn)接口。實(shí)現(xiàn)是綁定的具體某個(gè)實(shí)例上的,這個(gè)實(shí)例是通過(guò) new 來(lái)創(chuàng)建的,而不是整個(gè)類(lèi)。這樣做有一些好處,例如運(yùn)行時(shí)的內(nèi)存占用,因?yàn)?Nashorn 可以為每個(gè)實(shí)現(xiàn)的類(lèi)型組合創(chuàng)建一個(gè)單一的通用適配器。
下面的例子展示不同的實(shí)例可以是同一個(gè) Java 類(lèi),而其 JavaScript 實(shí)現(xiàn)對(duì)象卻是不同的:
var Runnable = java.lang.Runnable; var r1 = new Runnable(function() { print("I'm runnable 1!") }); var r2 = new Runnable(function() { print("I'm runnable 2!") }); r1.run(); r2.run(); print("We share the same class: " + (r1.class === r2.class));
上述代碼將打印如下結(jié)果:
I'm runnable 1! I'm runnable 2! We share the same class: true
如果你想傳遞類(lèi)的實(shí)例給外部 API(如 JavaFX 框架,傳遞 Application 實(shí)例給 JavaFX API),你必須擴(kuò)展一個(gè) Java 類(lèi)或者實(shí)現(xiàn)了與該類(lèi)綁定的接口,而不是它的實(shí)例。你可以通過(guò)傳遞一個(gè) JavaScript 對(duì)象綁定實(shí)現(xiàn)類(lèi)并傳遞給 Java.extend() 函數(shù)的最后一個(gè)參數(shù)。這個(gè)會(huì)創(chuàng)建一個(gè)跟原有類(lèi)包含一樣構(gòu)造函數(shù)的新類(lèi),因?yàn)樗鼈儾恍枰~外實(shí)現(xiàn)對(duì)象參數(shù)。
下面的例子展示如何綁定實(shí)現(xiàn)到類(lèi)中,并演示在這種情況下對(duì)于不同調(diào)用的實(shí)現(xiàn)類(lèi)是不同的:
var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") }); var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") }); var r1 = new RunnableImpl1();var r2 = new RunnableImpl2(); r1.run(); r2.run(); print("We share the same class: " + (r1.class === r2.class));
上面例子執(zhí)行結(jié)果如下:
I'm runnable 1! I'm runnable 2! We share the same class: false
將實(shí)現(xiàn)對(duì)象從構(gòu)造函數(shù)調(diào)用移到 Java.extend()
函數(shù)調(diào)用可以避免在構(gòu)造函數(shù)調(diào)用中所需的額外參數(shù)。每一個(gè) Java.extend()
函數(shù)的調(diào)用都需要一個(gè)指定類(lèi)的實(shí)現(xiàn)對(duì)象生成一個(gè)新的 Java 適配器類(lèi)。帶類(lèi)邊界實(shí)現(xiàn)的適配器類(lèi)仍可以使用一個(gè)額外的構(gòu)造參數(shù)用來(lái)進(jìn)一步重寫(xiě)特定實(shí)例的行為。因此你可以合并這兩種方法:你可以在一個(gè)基礎(chǔ)類(lèi)中提供部分 JavaScript 實(shí)現(xiàn),然后傳遞給 Java.extend()
函數(shù),以及在對(duì)象中提供實(shí)例實(shí)現(xiàn)并傳遞給構(gòu)造函數(shù)。對(duì)象定義的函數(shù)并傳遞給構(gòu)造函數(shù)時(shí)將覆蓋對(duì)象的一些函數(shù)定義。
下面的代碼演示如何通過(guò)給構(gòu)造函數(shù)傳遞一個(gè)函數(shù)來(lái)覆蓋類(lèi)邊界對(duì)象的函數(shù):
var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") }); var r1 = new RunnableImpl(); var r2 = new RunnableImpl(function() { print("I'm runnable 2!") }); r1.run(); r2.run(); print("We share the same class: " + (r1.class === r2.class));
上面例子執(zhí)行后打印結(jié)果如下:
I'm runnable 1! I'm runnable 2! We share the same class: true
9、選擇方法重載變體
Java 的方法可以通過(guò)使用不同的參數(shù)類(lèi)型進(jìn)行重載。Java 編譯器 (javac) 會(huì)在編譯時(shí)選擇正確的方法來(lái)執(zhí)行。在 Nashorn 中對(duì)Java 重載方法的解析實(shí)在方法被調(diào)用的時(shí)候執(zhí)行的。也是根據(jù)參數(shù)類(lèi)型來(lái)確定正確的方法。但如果實(shí)際的參數(shù)類(lèi)型會(huì)導(dǎo)致模棱兩可的情況下,我們可以顯式的指定具體某個(gè)重載變體。這會(huì)提升程序執(zhí)行的性能,因?yàn)?Nashorn 引擎無(wú)需在調(diào)用過(guò)程中去辨別該調(diào)用哪個(gè)方法。
重載的變種作為特別的屬性暴露出來(lái)。我們可以用字符串的形式來(lái)引用它們,字符串包含方法名稱(chēng)、參數(shù)類(lèi)型,兩者使用圓括號(hào)包圍起來(lái)。
下面的例子顯示如何調(diào)用 System.out.println()
方法帶 Object
參數(shù)的變種,我們傳遞一個(gè) “hello” 字符串給它:
var out = java.lang.System.out; out["println(Object)"]("hello");
上述的例子中,光使用 Object 類(lèi)名就足夠了,因?yàn)樗俏ㄒ粯?biāo)識(shí)正確的簽名。你必須使用完整的類(lèi)名的情況是兩個(gè)重載變種函數(shù)使用不同的參數(shù)類(lèi)型,但是類(lèi)型的名稱(chēng)相同(這是可能的,例如不同包中包含相同的類(lèi)名)。
10、映射數(shù)據(jù)類(lèi)型
絕大多數(shù) Java 和 JavaScript 之前的轉(zhuǎn)換如你所期待的運(yùn)行良好。前面的章節(jié)中我們提到過(guò)一些簡(jiǎn)單的 Java 和 JavaScript 之間的數(shù)據(jù)類(lèi)型映射。例如可以顯式地轉(zhuǎn)換數(shù)組類(lèi)型數(shù)據(jù),JavaScript 函數(shù)可以在當(dāng)成參數(shù)傳遞給 Java 方法時(shí)自動(dòng)轉(zhuǎn)換成 SAM 類(lèi)型。每個(gè) JavaScript 對(duì)象實(shí)現(xiàn)了 java.util.Map
接口來(lái)讓 API 可以直接接受映射。當(dāng)傳遞數(shù)值給 Java API 時(shí),會(huì)被轉(zhuǎn)成所期待的目標(biāo)數(shù)值類(lèi)型,可以是封裝類(lèi)型或者是原始數(shù)據(jù)類(lèi)型。如果目標(biāo)類(lèi)型不太確定(如 Number),你只能要求它必須是 Number 類(lèi)型,然后專(zhuān)門(mén)針對(duì)該類(lèi)型是封裝了 Double、Integer 或者是 Long 等等。內(nèi)部的優(yōu)化使得數(shù)值可以是任何封裝類(lèi)型。同事你可以傳遞任意 JavaScript 值給 Java API,不管是封裝類(lèi)型還是原始類(lèi)型,因?yàn)?JavaScript 的 ToNumber
轉(zhuǎn)換算法將會(huì)自動(dòng)處理其值。如果 Java 方法要求一個(gè) String
或者 Boolean
對(duì)象參數(shù),JavaScript 將會(huì)使用 ToString
和 ToBoolean
轉(zhuǎn)換來(lái)獲得其值。
注意:
因?yàn)閷?duì)字符串操作的內(nèi)部性能優(yōu)化考慮,JavaScript 字符串并不總是對(duì)應(yīng) java.lang.String 類(lèi)型,也可能是 java.lang.CharSequence
類(lèi)型。如果你傳遞一個(gè) JavaScript 字符串給要求 java.lang.String
參數(shù)的 Java 方法,那么這個(gè) JavaScript 字符串就是 java.lang.String
類(lèi)型,但如果你的方法簽名想要更加泛型化(例如接受的參數(shù)類(lèi)型是 java.lang.Object),那么你得到的參數(shù)對(duì)象就會(huì)使一個(gè)實(shí)現(xiàn)了 CharSequence
類(lèi)的對(duì)象,而不是一個(gè) Java 字符串對(duì)象。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)和工作能有一定的幫助,如果有疑問(wèn)大家可以留言交流。
相關(guān)文章
微信小程序?qū)崿F(xiàn)一張或多張圖片上傳(云開(kāi)發(fā))
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)一張或多張圖片上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09Auntion-TableSort javascript類(lèi)文件
Auntion-TableSort javascript類(lèi)文件...2007-11-11Threejs實(shí)現(xiàn)滴滴官網(wǎng)首頁(yè)地球動(dòng)畫(huà)功能
這篇文章主要介紹了Threejs實(shí)現(xiàn)滴滴官網(wǎng)首頁(yè)地球動(dòng)畫(huà)效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07微信小程序wxml不能使用Array.includes條件判斷解決方法
這篇文章主要為大家介紹了微信小程序wxml不能使用Array.includes條件判斷解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11JavaScript實(shí)現(xiàn)表單全選或反選效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)表單全選或反選效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06微信小程序踩坑記錄之解決tabBar.list[3].selectedIconPath大小超過(guò)40kb
這篇文章主要給大家介紹了關(guān)于微信小程序踩坑記錄之解決tabBar.list[3].selectedIconPath大小超過(guò)40kb的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07