在Scala中涉及java泛型的java列表上迭代

在Scala中涉及java泛型的java列表上迭代,scala,Scala,我有一个来自第三方java库的API,看起来像: public List<?> getByXPath(String xpathExpr) defined on a class called DomNode 但是我在node.getByXPath上遇到编译错误。 错误:类型不匹配;找到:com.html.doElement=>所需单元:?0=>?哪种类型?0 如果我将其更改为: node.getByXPath(xpath).toList.foreach {node =>

我有一个来自第三方java库的API,看起来像:

public List<?> getByXPath(String xpathExpr)

defined on a class called DomNode
但是我在node.getByXPath上遇到编译错误。 错误:类型不匹配;找到:com.html.doElement=>所需单元:?0=>?哪种类型?0

如果我将其更改为:

node.getByXPath(xpath).toList.foreach {node => 

   node.insertBefore(otherNode)   

}
然后错误消失,但我在node.insertBeforeotherNode上得到错误 错误:值insertBefore不是?0的成员


这个问题的答案是什么?

你必须投下它。即

node.getByXPath(xpath).toList.foreach {node => 
   node.asInstanceOf[DomElement].insertBefore(otherNode)   
}
在Java中,由于列表元素的类型未知,您可能会遇到同样的问题

我假设每个元素实际上都是一个domeElement

编辑:

丹尼尔是对的,有更好的方法。例如,与ClassCastException或MatchError相比,您可以抛出更好的异常。例如

node.getByXPath(xpath).toList.foreach { 
    case node: DomElement => node.insertBefore(otherNode)  
    case _: => throw new Exception("Expecting a DomElement, got a " + node.getClass.getName)   
}
这样做:

node.getByXPath(xpath).toList.foreach { 
    case node: DomElement => node.insertBefore(otherNode)   
}
通过使用case,可以将其转换为模式匹配函数。如果返回了任何非domeElement,您将得到一个异常-如果需要,您可以为默认案例添加另一个案例匹配来处理它


你不应该做的是使用替代。这就放弃了任何类型的安全性,几乎没有任何好处。

这是一个很好的观点,至少对于部分功能,如果它不是DomeElement,您有机会做一些事情。但是,如果您不提供另一个cast,它基本上等同于cast——如果不是预期的类型,您将得到一个异常。
node.getByXPath(xpath).toList.foreach { 
    case node: DomElement => node.insertBefore(otherNode)   
}