如何解决Java泛型<?>以及如何在Scala中处理?
| 我有一个API(来自第三方Java库),看起来像: public List<?> getByXPath(String xpathExpr)
在名为DomNode的类上定义
我在scala函数中尝试这个:
1: def removeChild(node: DomNode,xpath: String) {
2: val lst: List[?] = node.getByXPath(xpath)
3: val child: DomNode = lst(0)
4: child.getParentNode().removeChild(child)
}
但它不能在scala中编译。我在第2行出现错误。
根据答案,我修改了它,现在是:
1: def removeChild(node: DomNode,xpath: String) {
2: val lst = node.getByXPath(xpath)
3: val child = lst(0).asInstanceOf[DomNode]
4: child.getParentNode().removeChild(child)
}
现在,我在第3行出现错误:类型为java.util.List [?0]的lst不带参数
我也尝试了val lst: List[_] = node.getByXPath(xpath)
,但这在同一行上给了我错误:
type mismatch;
found : java.util.List[?0] where type ?0
required: scala.List[_]
所以我仍然被困住。
解决方法
在第3行重新输入您的错误:请记住,这是一个Java列表,而不是Scala列表,因此请尝试
val child = lst.get(0).asInstanceOf[DomNode]
, 这是您的代码有什么问题:
def removeChild(node: DomNode,xpath: String) {
val lst: List[?] = node.getByXPath(xpath)
/* ^^^^^^^ This probably refers to scala.collection.immutable.List,which is a totally different type from the
java.util.List that getByXPath returns.*/
/* Also,the ? needs to be changed into an _ in Scala */
val child: DomNode = lst(0)
/* Two problems here: First,java.util.List won\'t support indexing
with parentheses. Second,you need to typecast the result to get a
DomNode. */
child.getParentNode().removeChild(child)
}
这是更正的版本:
import scala.collection.JavaConversions._
def removeChild(node:DomNode,xpath:String) {
val lst:scala.collection.Seq[_] = node.getByXPath(xpath)
/* triggers an implicit conversion that wraps the Java List in a Scala Seq */
val child: DomNode = lst(0).asInstanceOf[DomNode]
child.getParentNode().removeChild(child)
}
(省去类型注释仍然可以工作,当您分配val lst
时,它不会引起转换,而当您尝试调用lst(0)
时,它将引起转换。)
另一个无法转换为ScalaSeq
的更正版本:
def removeChild(node:DomNode,xpath:String) {
val lst:java.util.List[_] = node.getByXPath(xpath)
/* you can remove the type annotation here,but I left it in
for pedagogical purposes */
val child: DomNode = lst.get(0).asInstanceOf[DomNode]
child.getParentNode().removeChild(child)
}
, 以下为我工作:
val arr = DomNode.getByXPath(\"foo\").toArray
val child = lst(0).asInstanceOf[DomNode]
显然,通配符Java列表没有隐式转换为Scala列表,因此,您创建的val lst
类型为java.util.list
,当然它没有应用方法。我只是通过从列表中创建一个Scala数组来解决此问题。
, 这应该工作:
val lst: java.util.List[_] = node.getByXPath(xpath)
, 这是我的看法:
def removeChild(node: DomNode,xpath: String) {
// Let type inference do the work for you
// val lst: List[?] = node.getByXPath(xpath)
val lst = node.getByXPath(xpath)
// Also,do not confuse Java\'s and Scala\'s collections
// val child: DomNode = lst(0)
val child = lst.get(0)
// Finally,since you do not have a static guarantee of the type,// match on it
// child.getParentNode().removeChild(child)
child match {
case domNode: DomNode => domNode.getParentNode().removeChild(domNode)
case _ =>
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。