Scala错误:类型不匹配;找到:java.util.List [?0]必需:java.util.List [B]

时间:2018-11-09 18:18:51

标签: scala

我有下面的Scala代码。

此函数定义类型参数类型EntityManager,它是spring.jpa.properties.javax.persistence.lock.timeout=600的子类。它将B转换为A

java.util.List[A]

编译该程序时,出现以下错误。

java.util.List[B]

我的程序出了什么问题。我该如何解决该错误

1 个答案:

答案 0 :(得分:3)

使用java.util.stream.Stream.map时似乎发生了类型擦除(从Animal到?0),无论传入的是B还是具体类型,可能是由于Scala类型推断与Java类型推断之间的不兼容。

在调用Java方法时,您仍然需要泛型类型推断,则需要专门传递泛型类型:

def convertLowerBound[ B <: Animal] (a: JList[Animal]): JList[B] = a.stream().map[B](a => a.asInstanceOf[B]).collect(Collectors.toList[B]())

那么您就可以成功进行操作了:

scala> def convertLowerBound[ B <: Animal] (a: JList[Animal]): JList[B] = a.stream().map[B](a => a.asInstanceOf[B]).collect(Collectors.toList[B]())
convertLowerBound: [B <: Animal](a: java.util.List[Animal])java.util.List[B]

scala> convertLowerBound[Cat](a)
res30: java.util.List[Cat] = [Cat@6325af19, Dog@6ff6743f]

另一方面,您的转换并没有真正的用处,因为在运行时,所有通用类型都将被删除,因此编译后List [A]或List [B]将相同(它们将成为对象列表)您可以看一下已编译的字节码)。您可以直接在列表上直接投射,而不是在每个元素上直接投射

def convertLowerBound[B <: Animal : TypeTag] (a: JList[Animal]) = a.asInstanceOf[JList[B]]

然后您可以成功完成用例:

scala> a.add(new Cat())
res16: Boolean = true

scala> convertLowerBound[Cat](a)
res17: java.util.List[Cat] = [Cat@6325af19]

但是,如果类型不匹配,例如您在列表中添加了Dog并尝试将其投射为Cat列表,只有在您尝试访问元素时才会发生错误:

scala> a.add(new Dog())
res19: Boolean = true

scala> convertLowerBound[Cat](a)
res20: java.util.List[Cat] = [Cat@6325af19, Dog@6ff6743f]

scala> convertLowerBound[Cat](a).get(1)
java.lang.ClassCastException: Dog cannot be cast to Cat
  ... 28 elided