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

Why does List<Object[]> needs explicit casting to convert into Scala collection?

假设我有以下 Java 集合:

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

而且,从 Scala 中,我想引用该集合,将其转换为 Scala 集合,然后 return 一个 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
 }

...成功了!

现在我的问题是:为什么这是必要的?有没有办法避免这种显式转换?

改变

def convertMethod[Array[AnyRef]]() =

def convertMethod() =

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

原因很简单。在 convertMethod 中,Array 是一个类型参数,因此 而不是 指的是 scala.Array

你应该改变这个:

def convertMethod[Array[AnyRef]]()

对此:

def convertMethod()

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