Having trouble creating Scala delegate for java.util.Collection#toArray
The method defined in the Java API:
interface Collection<T> {
<X> X[] toArray(X[] a);
}
I attempt to do something like this in Scala:
class SCollection[T] extends Collection[T] {
val queue = new LinkedBlockingQueue[T]
def toArray[X](a: Array[X]) : Array[X] = queue.toArray(a)
}
I've left out the other methods in the interface for clarity. The compiler complains with:
overloaded method value toArray with alternatives:
[T](x$1: Array[T with java.lang.Object])Array[T with java.lang.Object] <and>开发者_如何学Go;
()Array[java.lang.Object]
cannot be applied to (Array[X])
def toArray[X](a: Array[X]) : Array[X] = queue.toArray(a)
^
How do I successfully override the toArray(..) method?
The compiler complains because you have to make sure that you do not pass primitive arrays like e.g. Array[Int]
(which maps to int[]
in Java).
You can write your method like this:
override def toArray[X](a: Array[X with AnyRef]) = queue.toArray[X](a)
Arrays are the only reified "collection" type on the jvm, so to build an array you need to know the exact type at runtime. Not such an easy thing to do after erasure...
If you look at how toArray
is implemented on Scala collections, you'll see that it uses a Manifest
to recover the erased type information. You basically need to duplicate this, and ensure a Manifest is available for your type T
.
However, why are you implementing this class in the first place? If you're trying to create a custom collection class, you'll find it quickly becomes very challenging to add features such as CanBuildFrom
. If you simply want a wrapper to offer a java Collection
to some other library, then I'd recommend JavaConvertors
instead. If you don't need interop, then there's no reason to implement Collection
at all, as Scala has a distinct collection framework and typically avoids Java's collections, which are broken for use in fully type safe functional programming.
精彩评论