鉴于以下情况,使用Oracle JRE 6运行会给出输出boo,但是OpenJDK 6会给出异常
javax.script.ScriptException: sun.org.mozilla.javascript.EvaluatorException: The choice of Java
constructor replace matching JavaScript argument types (function,string) is ambiguous; candidate
constructors are:
class java.lang.String replace(char,char)
class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence) (<Unknown source>#1)
in <Unknown source> at line number 1
大概是因为使用OpenJDK(可能附带了rt.jar),该函数获取了java.lang.String,而使用Oracle的函数获取了JavaScript String(或可以隐式强制为1).
那么哪个更正确? Javascript(在这种情况下)是API,那么我们可以编写Java使得API对于任一实现都是相同的吗? (如果OpenJDK实现“更正确”(并且将来很可能会成为每个人所做的事情),那么我猜想适当地更改API(文档,示例,测试)并抛出新的String(…)并非不可能,但是除非我更有信心,否则我不愿丑化API.)
import javax.script.*;
class st {
public static void main(String[] args) {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
Bindings bindings = jsEngine.getBindings(ScriptContext.ENGINE_SCOPE);
Foo foo = new Foo();
bindings.put("v", foo);
try {
jsEngine.eval("v.run(function(a) {println(a.replace(/f/,\"b\"));})");
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
}
和
public class Foo {
public void run(FooCB cb) {
cb.run("foo");
}
public static interface FooCB {
public void run(Object val);
}
}
解决方法:
Java SE 6规范(JSR 270)仅表示:
There will be no requirement that any
particular scripting language be
supported by the platform;
implementors may choose to include
support for the scripting language(s)
of their choice as they see fit.
据我所知,没有关于如何将Java类型集成到JavaScript中的正式规范.不幸的是,但是没有理由期望实现之间具有100%的兼容性.
我相信Rhino随附Oracle JRE和OpenJDK,但不能保证版本级别,补丁程序等.