Java 和 Scala 如何調(diào)用變參
Java 和 Scala 都支持變參方法, 寫在最后的位置上,最基本的調(diào)用方式也都是一樣的,一個個羅列過去。也可以傳入數(shù)組參數(shù),因?yàn)樽儏⒈举|(zhì)上就是一個數(shù)組,就是把 ... 開始位置到最后一個參數(shù)都收納到數(shù)組中去,所以變參之所以要放在最后的位置上,且一個方法中最多只能有一個變參類型。
這里主要是對比 Scala 對變參方法的調(diào)用,基本調(diào)用法當(dāng)然是沒問題的,但是在傳入數(shù)組作為變參的參數(shù)列表與 Java 相對時就稍有變化了。
另外提一下,如果想傳入 List 作為變參列表,而不是整體作為變參的第一個元素就是調(diào)用集合的 toArray() 方法轉(zhuǎn)換成一個數(shù)組傳入。
下面看 Java 中對變參方法的調(diào)用,參數(shù)列表和數(shù)組
public class JavaVarArgs {
public static void main(String[] args) {
foo("a", "b", "c");
foo(new String[]{"d", "e"});
}
public static void foo(String...params) {
System.out.println(params + " : " + params.length);
for(String s: params) {
System.out.println(s);
}
}
}
從輸出結(jié)果能夠很明白的看出變參 params 實(shí)際上就是一個數(shù)組
[Ljava.lang.String;@3f91beef : 3
a
b
c
[Ljava.lang.String;@1a6c5a9e : 2
d
e
我們知道 Scala 和 Java 之間可以互相調(diào)用,現(xiàn)在寫一段 Scala 代碼來調(diào)用 foo() 方法
object ScalaVarArgs {
def main(args: Array[String]) {
JavaVarArgs.foo("a", "b", "c")
// JavaVarArgs.foo(Array[String]("d", "e"))
}
}
JavaVarArgs.foo("a", "b", "c") 調(diào)用沒問題
而 JavaVarArgs.foo(Array[String]("d", "e")) 會有編譯問題
Type mismatch: expected String, actual Array[String]
Java 在調(diào)用變參方法時可以直接傳入相應(yīng)類型的數(shù)組,而 Scala 確不允許這么做了,因它試圖把 Array[String] 整體作為一個元素傳遞給 foo() 方法,而 foo() 要求的元素類型是字符串,所以編譯不過。
而 Scala 這時該如何使得與 Java 調(diào)用變參方法時的行為一致呢,那就是在調(diào)用時再附加說明:是要把數(shù)組中的元素逐個傳遞級變參,寫法
JavaVarArgs.foo(Array[String]("d", "e") :_*)
這樣的調(diào)用輸出就是
[Ljava.lang.String;@7a718e31 : 2
d
e
如果從上面的例子說來,我們的運(yùn)氣還不錯,因?yàn)榫幾g器告訴了你出現(xiàn)了什么問題。最麻煩的問題總是在能編譯,但運(yùn)行時詭異的情況。
因?yàn)樵谖冶救藢?shí)際中遭遇到的情形是變參類型是 Object 的方法,形如
public static void foo(Object...params) {
System.out.println(params + " : " + params.length);
for(Object o: params) {
System.out.println(o);
}
}
上面把參數(shù)改為 Object...params, 不會改變 Java 傳數(shù)組調(diào)用它的行為,但卻增加了 Scala 調(diào)用它時的排錯難度。
在 Scala 中使用 foo(Array[String]("d", "e") 調(diào)用并沒有編譯錯誤,加入上面的調(diào)試代碼才發(fā)現(xiàn),不管傳入多大的數(shù)組,總是輸出像
[Ljava.lang.Object;@7814d044 : 1
[Ljava.lang.String;@ea25c1
說方法只接收到了一個元素,類型被識別為形參的類型,不過進(jìn)一步遍歷變參,發(fā)現(xiàn)第一個元素是一個字符串?dāng)?shù)組,所以 Scala 把 Array[String]("d", "e") 整體作為 params 的第一個元素傳給了 foo() 方法。寫成
foo(Array[String]("d", "e") : _*)
是為了把數(shù)組拆散了傳給 foo() 方法。
起初以為是 Scala 調(diào)用 Java 的變參方法需要這么做,后來重新用 Scala 實(shí)現(xiàn)下變參方法
def foo(params: AnyRef*) {
println(params + " : " + params.length)
for (s <- params) {
println(s)
}
}
用 Scala 代碼來調(diào)用它,傳入數(shù)組,如果不想整體作為一個元素時也必須加上 : _* 參數(shù)說明,同樣的:
foo(Array[String]("d", "e") :_*)
在寫這篇之前,我所認(rèn)定的這是 Scala 調(diào)用變參方法的一個缺陷,: _* 似乎是一種默認(rèn)行為,現(xiàn)在認(rèn)為這恰恰是 Scala 的一個靈活性所在。Scala 提供了兩種方式來傳遞數(shù)組給變參,而為何 Java 不讓數(shù)組整體作為變參的一個元素呢,不過 Scala 放開這一特性,當(dāng)變參為 Object... params 確實(shí)放大了 Bug 的出現(xiàn)機(jī)率。
以上就是Java 和 Scala 如何調(diào)用變參的詳細(xì)內(nèi)容,更多關(guān)于Java 和 Scala 調(diào)用變參的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
redis.clients.jedis.exceptions.JedisAskDataException異常解決
redis.clients.jedis.exceptions.JedisAskDataExceptio異常是在使用Jedis客戶端與Redis集群交互時遇到的一種重定向異常,本文就來介紹一下解決方法,感興趣的可以了解一下2024-05-05
Sentinel自定義異常的三種實(shí)現(xiàn)方式
Spring Cloud Alibaba Sentinel 是目前主流并開源的流量控制和系統(tǒng)保護(hù)組件,Spring Cloud Alibaba Sentinel 有 3 種自定義異常的實(shí)現(xiàn)方式,本文小編將通過代碼示例給大家詳細(xì)的介紹這三種實(shí)現(xiàn)方式,需要的朋友可以參考下2023-11-11
Java網(wǎng)絡(luò)編程之IO模型阻塞與非阻塞簡要分析
這篇文章主要介紹Java網(wǎng)絡(luò)編程中的IO模型阻塞與非阻塞簡要分析,文中附有示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09
Maven根據(jù)不同環(huán)境打包不同配置文件的方法
這篇文章主要介紹了Maven根據(jù)不同環(huán)境打包不同配置文件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
java使用freemarker模板生成html再轉(zhuǎn)為pdf
這篇文章主要為大家詳細(xì)介紹了java如何使用freemarker模板生成html,再利用iText將生成的HTML轉(zhuǎn)換為PDF文件,感興趣的小伙伴可以參考下2025-04-04
Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動態(tài)路由
這篇文章主要介紹了Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動態(tài)路由的方法,幫助大家實(shí)現(xiàn)路由信息的自動更新,感興趣的朋友可以了解下2020-10-10

