scala和java几乎没有区别,可以互相调用。注意这里说的是几乎,总有那么少数,出人意料的惊喜在告诉你,scala就是scala。
一个例子
|
|
如上所示,这个例子很简单,把一个jabva的map转换成json字符串。
其中JSON.toJSONString的代码如下:
问题来了,上面的测试用例报错了:
错误的原因很明显,编译器在编译scala调用java依赖包里面的toJSONString函数时发生了歧义。
scala含有变参的重载函数
看一段代码:
上述代码分别输出:2、3、4
对于前两个构造函数,刚好对应了文章开头的例子,说明,scala调用类似的scala依赖是没有问题的。
我们来注意一下scala如何调用变参:当你使用Foo(2, 3)调用时候,会出现歧义,因为(2, 3)可以匹配到第二个和第三个构造函数。所以,就只能用看起来很奇怪的写法Foo(2, Array(3).toSeq: _*)来进行区分。Array(3).toSeq: _*就是在告诉编译器,这个参数是变参的,别匹配错了。
然后,我们来看看Java怎么做的。
java含有变参的重载函数
代码就不写了,总之,java调用java类似的函数也是没有问题的。
那么问题来了,为什么scala调用java类似的函数就有问题呢?要回答这个问题,我们先来看看java在进行重载调用时,编译器都做了些啥?
- 调用方法时,能与固定参数函数以及可变参数都匹配时,优先调用固定参数方法。
- 调用方法时,两个变长参数都匹配时,编译无法通过。
12345678910111213 public class VariVargsTest2 {public static void main(String[] args) {test("hello"); //1}public static void test(String ...args){System.out.println("变长参数1");}public static void test(String string,String...args){System.out.println("变长参数2");}}
当没有1处代码时,程序是能够编译通过的。但是当添加了1处代码后无法通过编译,给出的错误是:The method test(String[]) is ambiguous for the type VariVargsTest2。编译器不知道选取哪个方法。
总结
从scala和java对含有变参的重载函数处理的方式上,我们可以知道文章开头的代码为什么编译不过。
- scala首先会自己匹配,自己匹配不了的时候,使用者可以手动来标识变参参数。
- java自己匹配,并有一个自己的调用优先级顺序,实在分不清就编译不过了。
回到开头的问题,scala调用java出问题了,就应该是scala编译器和java编译器在处理这个问题时的差异导致的吧。