为什么List <object []>需要显式转换才能转换为Scala集合?

时间:2015-10-13 11:57:03

标签: java scala casting scala-collections

说我有以下Java集合:

public static List<Object[]> javaStuff = new ArrayList<Object[]>();

而且,从Scala开始,我想引用该集合,将其转换为Scala集合并在其上返回Iterator[]

任何人都可以向我解释为什么以下(玩具)代码无法编译?

def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
   import scala.collection.JavaConverters._
   val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala // This does not compile!  
   r.iterator
}

更具体地说,IntelliJ突出显示的错误是:
Expression of type Buffer[Array[AnyRef]] does not conform to expected type Buffer[Array[AnyRef]]

......这是非常缺乏信息的。试图运行代码,错误更有帮助:

Error:(18, 58) type mismatch;
found   : scala.collection.mutable.Buffer[scala.Array[Object]]
required: scala.collection.mutable.Buffer[Array[AnyRef]]
   val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala
                                 ^

此时,我将原始代码更改为:

def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
   import scala.collection.JavaConverters._
   val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala.map(_.asInstanceOf[Array[AnyRef]])
   r.iterator
 }

......它有效!

现在我的问题是:为什么这有必要?有没有办法避免那种明确的演员?

2 个答案:

答案 0 :(得分:4)

原因很简单。在convertMethod中,Array是一个类型参数,因此根本不会引用scala.Array

你应该改变这个:

def convertMethod[Array[AnyRef]]()

到此:

def convertMethod()

请注意,与shadowlands在评论中所说的相反,scala.Array与java数组实际上是相同的(除了scala数组不是协变的事实,但它不会在这里发挥作用)。

答案 1 :(得分:3)

更改

def convertMethod[Array[AnyRef]]() =

def convertMethod() =

第一个创建一个方法,该方法采用名称为Array的类型参数,该参数本身采用名称为AnyRef的类型参数(即更高的kinded类型)。这些新引入的名称隐藏了内置类型ArrayAnyRef