Учитывая следующее, при работе с 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 (или что-то, что может быть неявно приведено к одному).
Так что является более правильным?Javascript (в данном случае) - это API, поэтому можем ли мы написать Java так, чтобы API был одинаковым для любой реализации?(Если реализация OpenJDK «более правильная» (и, скорее всего, это будет то, что все сделают в будущем), то я думаю, что изменение API (документации, примеров, тестов), добавляющего new 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);
}
}