3

以下の場合、Oracle JRE 6 で実行するとブーイングが出力されますが、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 文字列 (または暗黙的に 1 つに強制できるもの) を取得しているためです。

では、どちらがより正しいでしょうか?Javascript (この場合) が API であるため、どちらの実装でも API が同じになるように Java を記述できますか? (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);
    }
}
4

1 に答える 1

3

Java SE 6 仕様 ( JSR 270 ) は単に次のように述べています。

特定のスクリプト言語がプラットフォームでサポートされている必要はありません。実装者は、必要に応じて、選択したスクリプト言語のサポートを含めることを選択できます。

私の知る限りでは、Java 型を JavaScript に統合する方法に関する正式な仕様はありません。残念ながら、実装間で 100% の互換性を期待する理由はありません。

Oracle JRE と OpenJDK の両方が Rhino に同梱されていると思いますが、バージョン レベルやパッチなどについての保証はありません。

于 2011-05-10T00:21:15.630 に答える