说我有以下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
}
......它有效!
现在我的问题是:为什么这有必要?有没有办法避免那种明确的演员?
答案 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类型)。这些新引入的名称隐藏了内置类型Array
和AnyRef
。