假设我有一个类似下面的Java API:
public class JavaApi<T> {
public void foo(T[] data) {
...
}
}
我想通过以下课程从Scala调用它:
class Caller[T] {
val javaApi = new JavaApi[T]()
def callApi(data: Array[T]) = javaApi.foo(data)
}
在编译时,我得到以下内容:
type mismatch;
found : Array[T]
required: Array[T with Object]
Note: T >: T with Object, but class Array is invariant in type T.
You may with to investigate a wildcard type such as `_ >: T with Object`. (SLS 3.2.10)
def callApi(data: Array[T]) = javaApi.foo(data)
答案 0 :(得分:0)
您可以查看Scala type hierarchy。更具体地说:
如果在Java运行时环境的上下文中使用Scala,那么 scala.AnyRef对应于java.lang.Object
因此,通过更改它,Jubobs建议您确定该类型对应于一个对象:
class Caller[T<: AnyRef] {
val javaApi = new JavaApi[T]()
def callApi(data: Array[T]) = javaApi.foo(data)
}
因此,如果您需要任何值类型,如int,char,boolean,则需要将它们转换为对象等效的盒装Java类型,如Integer,Character或Boolean。看到:
答案 1 :(得分:0)
这是由 Java 不支持primitive type的多态性引起的。
虽然 Scala 将任何内容视为对象,但在编译器编译之后,可能会将对象转换为基本类型数组用于提高性能,例如:
scala> var a = Array(1, 2, 3)
a: Array[Int] = Array(1, 2, 3)
scala> :javap -c a
public class $line3.$read$$iw$$iw$ {
...
public int[] a();
...
如您所见,上述Array[Int]
已转换为int[]
基本类型数组。
因此,这可能导致 Java 方法不兼容。
解决方案:
T
绑定到T <: AnyRef
。如val a = Array[Integer](1, 2, 3)
,编译器将其作为Integer[]
类型处理。List
替换Array
,List
始终reference
类型。参考: