无法为java.util.Collection#toArray创建Scala委托

时间:2011-03-01 23:17:00

标签: java scala

Java API中定义的方法:

interface Collection<T> {
  <X> X[] toArray(X[] a);
}

我尝试在Scala中执行类似的操作:

class SCollection[T] extends Collection[T] {
    val queue = new LinkedBlockingQueue[T]

    def toArray[X](a: Array[X]) : Array[X] = queue.toArray(a)
}

为清楚起见,我在界面中省略了其他方法。编译器抱怨:

overloaded method value toArray with alternatives:
  [T](x$1: Array[T with java.lang.Object])Array[T with java.lang.Object] <and>
  ()Array[java.lang.Object]
 cannot be applied to (Array[X])
  def toArray[X](a: Array[X]) : Array[X] = queue.toArray(a)
                                                 ^

如何成功覆盖toArray(..)方法?

2 个答案:

答案 0 :(得分:4)

编译器抱怨,因为你必须确保不传递原始数组,例如Array[Int](在Java中映射到int[]。)

你可以这样编写你的方法:

   override def toArray[X](a: Array[X with AnyRef]) = queue.toArray[X](a)

答案 1 :(得分:1)

数组是jvm上唯一的已知的“集合”类型,因此要构建数组,您需要在运行时知道确切的类型。擦除后不是一件容易的事情......

如果您查看在Scala集合上如何实现toArray,您会看到它使用Manifest来恢复已擦除的类型信息。您基本上需要复制此内容,并确保您的类型T可以使用清单。

但是,你为什么要首先实现这个课程呢?如果您正在尝试创建自定义集合类,您会发现添加CanBuildFrom等功能很快就会变得极具挑战性。如果您只是希望包装器向其他库提供java Collection,那么我建议使用JavaConvertors。如果你不需要互操作,那么根本就没有理由实现Collection,因为Scala有一个独特的集合框架,并且通常避免使用Java的集合,这些集合在完全类型安全的函数式编程中被破坏。