从 Scala 调用 Java 泛型类型化方法会给出类型不匹配错误:Scala



这是我在这里的第一个问题,所以我会尽量把它说清楚。 此处的其他error: type mismatch;问题与此错误无关。

我在scala/java互操作性方面遇到了一个奇怪的问题:

假设我们有一个Java类

public class JavaClass{
public static <T> T[] toArray(Class<T> t, Collection<T> coll) {
return null; // return null to make it simple
}
}

然后我还有另一个 Scala 类,我只想将此方法包装在:

object ScalaClass{
def toArray[T](t: java.lang.Class[T], coll: java.util.Collection[T]): Array[T] = {
JavaClass.toArray[T](t, coll);
}
}

编译 Scala 类给了我一个非常奇怪的错误:

error: type mismatch;

任何想法都是值得赞赏的。

编辑 1: 完整的错误消息是

[ERROR] ScalaScala.scala:4002: error: type mismatch;
[INFO]  found   : Array[T]
[INFO]  required: Class[T]
[INFO]  JavaClass.toArray[T](t, coll);
[INFO]                      ^

欢迎来到 SO。

这似乎是编译的,但我不确定它是否适用于JavaClass的实际实现,但我很确定它应该。

import scala.reflect.ClassTag
object ScalaClass {
def toArray[T <: AnyRef](coll: java.util.Collection[T])(implicit ct: ClassTag[T]): Array[T] =
JavaClass.toArray[T](ct.runtimeClass.asInstanceOf[Class[T]], coll)
}

要从Scala调用它,你只需要传递 java 集合,它会从类型中获取正确的类,如下所示:

val col: java.util.Collection[String] = ???
val array: Array[String] = ScalaClass.toArray(col)

编辑

如果要保留原始签名,则必须执行以下操作:

object ScalaClass {
def toArray[T <: AnyRef](t: java.lang.Class[T], coll: java.util.Collection[T]): Array[T] =
JavaClass.toArray[T](t, coll)
}

你可以像这样使用:

val col: java.util.Collection[String] = ???
val array: Array[String] = ScalaClass.toArray(classOf[String], col)

在这两种情况下,诀窍都是<: AnyRef类型绑定
恕我直言,第一个版本更符合人体工程学,可用于惯用的 Scala 代码。

最新更新