Java 和 Scala 如何调用变参
Java和Scala都支持变参方法,写在最后的位置上,最基本的调用方式也都是一样的,一个个罗列过去。也可以传入数组参数,因为变参本质上就是一个数组,就是把...开始位置到最后一个参数都收纳到数组中去,所以变参之所以要放在最后的位置上,且一个方法中最多只能有一个变参类型。
这里主要是对比Scala对变参方法的调用,基本调用法当然是没问题的,但是在传入数组作为变参的参数列表与Java相对时就稍有变化了。
另外提一下,如果想传入List作为变参列表,而不是整体作为变参的第一个元素就是调用集合的toArray()方法转换成一个数组传入。
下面看Java中对变参方法的调用,参数列表和数组
publicclassJavaVarArgs{ publicstaticvoidmain(String[]args){ foo("a","b","c"); foo(newString[]{"d","e"}); } publicstaticvoidfoo(String...params){ System.out.println(params+":"+params.length); for(Strings:params){ System.out.println(s); } } }
从输出结果能够很明白的看出变参params实际上就是一个数组
[Ljava.lang.String;@3f91beef:3
a
b
c
[Ljava.lang.String;@1a6c5a9e:2
d
e
我们知道Scala和Java之间可以互相调用,现在写一段Scala代码来调用foo()方法
objectScalaVarArgs{ defmain(args:Array[String]){ JavaVarArgs.foo("a","b","c") //JavaVarArgs.foo(Array[String]("d","e")) } }
JavaVarArgs.foo("a","b","c")调用没问题
而JavaVarArgs.foo(Array[String]("d","e"))会有编译问题
Typemismatch:expectedString,actualArray[String]
Java在调用变参方法时可以直接传入相应类型的数组,而Scala确不允许这么做了,因它试图把Array[String]整体作为一个元素传递给foo()方法,而foo()要求的元素类型是字符串,所以编译不过。
而Scala这时该如何使得与Java调用变参方法时的行为一致呢,那就是在调用时再附加说明:是要把数组中的元素逐个传递级变参,写法
JavaVarArgs.foo(Array[String]("d","e"):_*)
这样的调用输出就是
[Ljava.lang.String;@7a718e31:2
d
e
如果从上面的例子说来,我们的运气还不错,因为编译器告诉了你出现了什么问题。最麻烦的问题总是在能编译,但运行时诡异的情况。
因为在我本人实际中遭遇到的情形是变参类型是Object的方法,形如
publicstaticvoidfoo(Object...params){ System.out.println(params+":"+params.length); for(Objecto:params){ System.out.println(o); } }
上面把参数改为Object...params,不会改变Java传数组调用它的行为,但却增加了Scala调用它时的排错难度。
在Scala中使用foo(Array[String]("d","e")调用并没有编译错误,加入上面的调试代码才发现,不管传入多大的数组,总是输出像
[Ljava.lang.Object;@7814d044:1
[Ljava.lang.String;@ea25c1
说方法只接收到了一个元素,类型被识别为形参的类型,不过进一步遍历变参,发现第一个元素是一个字符串数组,所以Scala把Array[String]("d","e")整体作为params的第一个元素传给了foo()方法。写成
foo(Array[String]("d","e"):_*)
是为了把数组拆散了传给foo()方法。
起初以为是Scala调用Java的变参方法需要这么做,后来重新用Scala实现下变参方法
deffoo(params:AnyRef*){ println(params+":"+params.length) for(s<-params){ println(s) } }
用Scala代码来调用它,传入数组,如果不想整体作为一个元素时也必须加上:_*参数说明,同样的:
foo(Array[String]("d","e"):_*)
在写这篇之前,我所认定的这是Scala调用变参方法的一个缺陷,:_*似乎是一种默认行为,现在认为这恰恰是Scala的一个灵活性所在。Scala提供了两种方式来传递数组给变参,而为何Java不让数组整体作为变参的一个元素呢,不过Scala放开这一特性,当变参为Object...params确实放大了Bug的出现机率。
以上就是Java和Scala如何调用变参的详细内容,更多关于Java和Scala调用变参的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。