Java 和 Scala 如何調(diào)用變參
Java 和 Scala 都支持變參方法, 寫(xiě)在最后的位置上,最基本的調(diào)用方式也都是一樣的,一個(gè)個(gè)羅列過(guò)去。也可以傳入數(shù)組參數(shù),因?yàn)樽儏⒈举|(zhì)上就是一個(gè)數(shù)組,就是把 ... 開(kāi)始位置到最后一個(gè)參數(shù)都收納到數(shù)組中去,所以變參之所以要放在最后的位置上,且一個(gè)方法中最多只能有一個(gè)變參類型。
這里主要是對(duì)比 Scala 對(duì)變參方法的調(diào)用,基本調(diào)用法當(dāng)然是沒(méi)問(wèn)題的,但是在傳入數(shù)組作為變參的參數(shù)列表與 Java 相對(duì)時(shí)就稍有變化了。
另外提一下,如果想傳入 List 作為變參列表,而不是整體作為變參的第一個(gè)元素就是調(diào)用集合的 toArray() 方法轉(zhuǎn)換成一個(gè)數(shù)組傳入。
下面看 Java 中對(duì)變參方法的調(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í)際上就是一個(gè)數(shù)組
[Ljava.lang.String;@3f91beef : 3
a
b
c
[Ljava.lang.String;@1a6c5a9e : 2
d
e
我們知道 Scala 和 Java 之間可以互相調(diào)用,現(xiàn)在寫(xiě)一段 Scala 代碼來(lái)調(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)用沒(méi)問(wèn)題
而 JavaVarArgs.foo(Array[String]("d", "e")) 會(huì)有編譯問(wèn)題
Type mismatch: expected String, actual Array[String]
Java 在調(diào)用變參方法時(shí)可以直接傳入相應(yīng)類型的數(shù)組,而 Scala 確不允許這么做了,因它試圖把 Array[String] 整體作為一個(gè)元素傳遞給 foo() 方法,而 foo() 要求的元素類型是字符串,所以編譯不過(guò)。
而 Scala 這時(shí)該如何使得與 Java 調(diào)用變參方法時(shí)的行為一致呢,那就是在調(diào)用時(shí)再附加說(shuō)明:是要把數(shù)組中的元素逐個(gè)傳遞級(jí)變參,寫(xiě)法
JavaVarArgs.foo(Array[String]("d", "e") :_*)
這樣的調(diào)用輸出就是
[Ljava.lang.String;@7a718e31 : 2
d
e
如果從上面的例子說(shuō)來(lái),我們的運(yùn)氣還不錯(cuò),因?yàn)榫幾g器告訴了你出現(xiàn)了什么問(wèn)題。最麻煩的問(wèn)題總是在能編譯,但運(yùn)行時(shí)詭異的情況。
因?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, 不會(huì)改變 Java 傳數(shù)組調(diào)用它的行為,但卻增加了 Scala 調(diào)用它時(shí)的排錯(cuò)難度。
在 Scala 中使用 foo(Array[String]("d", "e") 調(diào)用并沒(méi)有編譯錯(cuò)誤,加入上面的調(diào)試代碼才發(fā)現(xiàn),不管傳入多大的數(shù)組,總是輸出像
[Ljava.lang.Object;@7814d044 : 1
[Ljava.lang.String;@ea25c1
說(shuō)方法只接收到了一個(gè)元素,類型被識(shí)別為形參的類型,不過(guò)進(jìn)一步遍歷變參,發(fā)現(xiàn)第一個(gè)元素是一個(gè)字符串?dāng)?shù)組,所以 Scala 把 Array[String]("d", "e") 整體作為 params 的第一個(gè)元素傳給了 foo() 方法。寫(xiě)成
foo(Array[String]("d", "e") : _*)
是為了把數(shù)組拆散了傳給 foo() 方法。
起初以為是 Scala 調(diào)用 Java 的變參方法需要這么做,后來(lái)重新用 Scala 實(shí)現(xiàn)下變參方法
def foo(params: AnyRef*) { println(params + " : " + params.length) for (s <- params) { println(s) } }
用 Scala 代碼來(lái)調(diào)用它,傳入數(shù)組,如果不想整體作為一個(gè)元素時(shí)也必須加上 : _* 參數(shù)說(shuō)明,同樣的:
foo(Array[String]("d", "e") :_*)
在寫(xiě)這篇之前,我所認(rèn)定的這是 Scala 調(diào)用變參方法的一個(gè)缺陷,: _* 似乎是一種默認(rèn)行為,現(xiàn)在認(rèn)為這恰恰是 Scala 的一個(gè)靈活性所在。Scala 提供了兩種方式來(lái)傳遞數(shù)組給變參,而為何 Java 不讓數(shù)組整體作為變參的一個(gè)元素呢,不過(guò) Scala 放開(kāi)這一特性,當(dāng)變參為 Object... params 確實(shí)放大了 Bug 的出現(xiàn)機(jī)率。
以上就是Java 和 Scala 如何調(diào)用變參的詳細(xì)內(nèi)容,更多關(guān)于Java 和 Scala 調(diào)用變參的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
淺談spring中isolation和propagation的用法
這篇文章主要介紹了淺談spring中isolation 和propagation的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Java實(shí)現(xiàn)圖片上傳至FastDFS入門教程
這篇文章主要介紹了Java實(shí)現(xiàn)圖片上傳至FastDFS入門教程,通過(guò)前端ajax提交圖片到后端,java處理服務(wù)器文件上傳至FastDFS文件服務(wù)器系統(tǒng),以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07Java整合mybatis實(shí)現(xiàn)過(guò)濾數(shù)據(jù)
這篇文章主要介紹了Java整合mybatis實(shí)現(xiàn)過(guò)濾數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理解析
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09OpenJDK源碼解析之System.out.println詳解
這篇文章主要介紹了OpenJDK源碼解析之System.out.println詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04java中char類型轉(zhuǎn)換成int類型的2種方法
這篇文章主要給大家介紹了關(guān)于java中char類型轉(zhuǎn)換成int類型的2種方法,因?yàn)閖ava是一門強(qiáng)類型語(yǔ)言,所以在數(shù)據(jù)運(yùn)算中會(huì)存在類型轉(zhuǎn)換,需要的朋友可以參考下2023-07-07java中利用反射調(diào)用另一類的private方法的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇java中利用反射調(diào)用另一類的private方法的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06java面向?qū)ο?API(接口)與集合(ArrayList)
這篇文章主要介紹了Java語(yǔ)言面向?qū)ο蟮腁PI與集合,還是十分不錯(cuò)的,這里給大家分享下,需要的朋友可以參考,希望能夠給你帶來(lái)幫助2021-08-08