Java将选择哪个JS脚本引擎?

Java将选择哪个JS脚本引擎?,java,rhino,nashorn,scriptengine,Java,Rhino,Nashorn,Scriptengine,ScriptEngineManager.getEngineByName查找并为给定名称创建ScriptEngine Rhino将自己注册为“js”、“Rhino”、“JavaScript”、“JavaScript”、“ECMAScript”和“ECMAScript” Nashorn将自己注册为“Nashorn”、“Nashorn”、“js”、“js”、“JavaScript”、“JavaScript”、“ECMAScript”和“ECMAScript” 如果我使用Nashorn和Rhino都注册

ScriptEngineManager.getEngineByName查找并为给定名称创建ScriptEngine

Rhino将自己注册为“js”、“Rhino”、“JavaScript”、“JavaScript”、“ECMAScript”和“ECMAScript”

Nashorn将自己注册为“Nashorn”、“Nashorn”、“js”、“js”、“JavaScript”、“JavaScript”、“ECMAScript”和“ECMAScript”

如果我使用Nashorn和Rhino都注册过的像“js”这样的名称,那么将使用哪个脚本引擎?它会在Java 8和Rhino上使用Nashorn吗?

查看for
registerEngineName

注册ScriptEngineFactory以处理语言名称。覆盖 使用发现机制发现的任何此类关联

并且在
注册表的EngineName
源代码处(注意
名称关联
是一个哈希映射):

因此,对于给定的名称,
getEngineByName
似乎将返回最后一个为该名称注册的脚本引擎工厂

由于脚本引擎工厂是通过该机制加载的,加载顺序将取决于相关类装入器方法枚举服务配置文件的顺序


对于默认安装,所有这些都无关紧要,因为Java8只包括Nashorn,Java7和更早版本只包括Rhino。如果您想通过系统类路径添加一个额外的引擎,它将在引导/扩展类加载器加载的引擎之后加载,因此优先。

读取代码,
registerEngineName
确实是确定的,但是发现机制是独立的(正如JavaDoc所暗示的),而且它是不确定的,因为它在发现过程中将所有引擎添加到
哈希集
,当按名称请求引擎时,它只使用找到的第一个匹配项

如果您在Java 7中安装并通过任何常用名称(
js
rhino
,等等)请求它,您可以遇到这种情况


但是,除非你这样做,否则Java 7和Java 8都只有一个实现,分别对应于
js
javascript
ecmascript
,等等。只要你不要求
rhino
nashorn
,它应该在这两种情况下都能工作,因为发现机制根本不使用
registerEngineName
。如果没有显式注册名称,那么实际上会得到从
哈希集中弹出的第一个匹配引擎。它比类加载器顺序更随机,因为它归结为
java.lang.Object.hashCode
,并且在每次运行中都有所不同。
public void registerEngineName(String name, ScriptEngineFactory factory) {
    if (name == null || factory == null) throw new NullPointerException();
        nameAssociations.put(name, factory);
}