Java Nashorn环境下如何正确实现NodeList类型的强制类型转换
Nashorn 环境下Java类型强制转换实现方案
此前报错的核心原因
- Nashorn 基于ECMAScript语法规范实现,完全不支持Java风格的强转语法。你写的
(NodeList) expr.evaluate(...)在JS解析阶段就会被判定为非法结构:解析器看到括号开头的语法时,只会将其识别为函数调用,碰到后面的expr标识符时,就会抛出“期望分号”的解析错误。 - 用
new NodeList(...)的写法报错,是因为org.w3c.dom.NodeList是Java定义的公开接口,本身不存在可访问的公开构造方法,脚本引擎自然会抛出“无法实例化”的类型错误。另外你从XPathevaluate方法拿到的返回值,本身就是实现了NodeList接口的DTMNodeList实例,根本不需要通过new的方式创建对象。
正确的类型转换写法
Nashorn 为Java互操作场景提供了专门的Java.cast()全局API,用来实现Java强转的等价效果,不需要依赖Java原生的语法结构:
- 按照原有方式加载目标Java类型:
NodeList = Java.type("org.w3c.dom.NodeList") - 对evaluate方法的返回值做类型标记:
objItem = Java.cast(NodeList, expr.evaluate(xmldoc, javax.xml.xpath.XPathConstants.NODESET))
该方法的运行逻辑是:不新建任何Java对象,只对已存在的对象做类型标记,后续无论是脚本调用对象方法,还是把这个对象作为参数传给其他Java方法,都会按照标记的类型做匹配,效果和Java代码里的
(NodeList)xxx强转完全一致。
补充说明
- 绝大多数场景下,甚至不需要调用
Java.cast做转换:XPath 返回的NODESET结果本身就是NodeList接口的实现类,直接调用getLength()、item(index)等NodeList定义的方法即可正常运行,Nashorn的Java互操作层会自动识别对应的方法签名。 Java.cast只在两种场景下是必须的:一是需要把这个对象作为参数传给Java方法,且方法存在多个重载,需要明确参数类型匹配;二是对象实现了多个存在同名方法的接口,需要消除脚本侧的方法调用歧义。
内容的提问来源于stack exchange,提问作者khushi
相关产品推荐
相关产品推荐

