不能隐含地将A [T]强制转换为AT,其中A [T]扩展为AT

时间:2013-04-08 11:04:25

标签: java scala generics

问题与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]”

任何人都可以解释为什么会这样,以及如何解决这个问题?

1 个答案:

答案 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()