问题与Java和Scala之间的集成有关。为了让事情更清楚,我简化了一点。
我有两个用Java编写的类:
class A<T>{}
class AT extends A<Boolean> {}
在Java中,我有一个方法,它以下列方式使用这些类:
public A<Boolean> a(){
return new AT();
}
我想在scala中做同样的事情。但是下面的代码不能编译。
def a(): A[Boolean] = {
return new AT();
}
消息说:“类型不匹配;找到:org.rarry.sample.AT required:org.rarry.sample.A [Boolean]”
任何人都可以解释为什么会这样,以及如何解决这个问题?
答案 0 :(得分:5)
要了解代码无法编译的原因,请首先注意Java使用java.lang.Boolean
作为盒装布尔类型,Scala使用scala.Boolean
。大多数情况下,当您想要使用其中一个,并且方法返回另一个(或方法参数需要另一个)时,将执行隐式转换,并将使用正确的类型。
您在Scala中编写的方法a
确实返回A[java.lang.Boolean]
。由于A[java.lang.Boolean]
和A[scala.Boolean]
之间没有隐式转换,因此在这种情况下不会自动返回A[scala.Boolean]
。
要验证是否是这种情况,我们可以看到此方法编译没有问题:
def a: A[java.lang.Boolean] = new AT()
重申一点,因为我们没有隐式转换,所以这也行不通(你会看到如何解决这个问题):
val instanceOfA: A[Boolean] = a
def a = new AT()
// Error: AT doesn't conform to A[Boolean]
要修复它,您可以通过强制转换为隐式转换为所需类型:
implicit def toScalaABoolean(a: A[java.lang.Boolean]): A[Boolean] =
a.asInstanceOf[A[Boolean]]
完成后,您甚至不必再声明a
方法的返回类型:
implicit def toDifferentBoolean(a: A[java.lang.Boolean]): A[Boolean] =
a.asInstanceOf[A[Boolean]]
val instanceOfA: A[Boolean] = a
def a = new AT()