键入翻译问题

时间:2017-02-09 14:05:29

标签: java scala types

我在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的子类并且可以添加到主列表中。

真的希望有人帮助我。我已经尝试了几种替代方案,但我无法做到这一点。我错过了什么,还是我真的很蠢?

谢谢, 阿达什讷

2 个答案:

答案 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代码部分,但据我所知,您正在尝试执行以下操作,

  1. 您有一些Constainer container的实例。
  2. 您希望获取该容器的元素并向其添加新元素。
  3. 如果您正在尝试这样做,那么您可以执行以下操作,

    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)