我在Java
中有以下类层次结构Class Container
{
private List<? extends Element> element;
public List<? extends Element> getElements()
{
return elements;
}
public void setElements(List<? extends Element> elements)
{
this.elements = elements;
}
}
MyElement extends Element
{
int a;
}
在我的scala服务中,我使用以下这些类 -
var elements: java.util.List[_ <: Element] = container getElements
elements match {
case null => elements = new ArrayList[MyElement]();
case _ => ;
}
//additional service code here,
//and then try to create an object and add it to the existing list of elements as below.
val element = new MyElement
//..... other prog logic..
elements.add(element)
将元素添加到列表
时出现编译错误我看到错误消息列为 -
type mismatch; found : element.type (with underlying type com.vo.MyElement) required: _$7 where type _$7 <: com.vo.Element
有什么方法可以解决这个问题吗?为什么Scala编译器无法解释MyElement确实是Element的子类并且可以添加到主列表中。
真的希望有人帮助我。我已经尝试了几种替代方案,但我无法做到这一点。我错过了什么,还是我真的很蠢?
谢谢, 阿达什讷
答案 0 :(得分:2)
如果您在Java中尝试过此操作,则会出现同样的问题(可能只有更有用的错误消息......)。
看一下下面的代码,想一想如果这个编译会发生什么。
trait Element
class MyElement extends Element
class MyOtherElement extends Element
import java.{ util => ju }
val myElements = new ju.ArrayList[MyElement]()
val elements: ju.List[_ <: Element] = myElements
elements.add(new MyOtherElement)
val myElement: MyElement = myElements.get(0)
顺便说一句,这与Java vs Scala无关:
import scala.collection.mutable.ListBuffer
val myElements = new ListBuffer[MyElement]()
val elements: ListBuffer[_ <: Element] = myElements
elements += new MyOtherElement
val myElement: MyElement = myElements(0)
原因是你在这里使用use-site variance,因为可变集合被定义为不变量。并且所有Java集合都是自动不变的,因为Java没有像Scala那样的声明 - 站点差异的概念,并且它的集合无论如何都是可变的。
答案 1 :(得分:0)
虽然,我不确定您的Java代码部分,但据我所知,您正在尝试执行以下操作,
Constainer
container
的实例。如果您正在尝试这样做,那么您可以执行以下操作,
val elements = {
if (container.getElements() != null) {
container.getElements()
}
else {
val list: java.util.List[_ <: Element] = new java.util.ArrayList[MyElement]()
list
}
}
val element = new MyElement
elements.add(element)