2016-05-11 3 views
0

潜在的に疑わしい質問ですが、ここでそれについての直接のドキュメントを見つけることができませんでした。toStringメソッドをnashornのjsオブジェクトに公開

Javaの "コンストラクタ"をJS側に公開したい場合は、インスタンス化する際に "toString"メソッドを使用してインスタンスを作成する必要があります。

// java class 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 
import jdk.nashorn.api.scripting.AbstractJSObject; 

public class Foo extends AbstractJSObject { 
    String bar; 

    public Foo() { 
     super(); 
    } 

    public Foo(String b) { 
     super(); 
     this.bar = b; 
    } 

    @Override 
    public Object newObject(Object... args) { 
     String bar = null; 
     if (args[0] != null) bar = args[0].toString(); 

     Foo f = new Foo(bar); 
     return f; 
    } 

    @Override 
    public String toString() { 
     return "Foo: " + this.bar; 
    } 


    public static void main(String[] args) { 
     ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 
     engine.put("foo", new Foo()); 

     // f.toString however is null 
     engine.eval("var f = new foo('hi'); f.toString();") 
    } 
} 
+0

あなたは現在これを実行していないコードをしていますか?あなたが概説したタスクで現在あなたが抱えている問題は何ですか? –

+0

@ PeterDavidCarter-Poulsenそうではありません。 toStringは新しいfoo(...)のインスタンスではnull –

答えて

1

あなたがのJSObjectを実装する場合、nashorn意志ルートのすべてのプロパティ/インデックスアクセス、getMember、getSlot、setMember、setSlot、呼び出し方法などのJSObjectのメソッドを使って呼び出します。私はあなたのFooオブジェクトのプロパティとして「のtoString」を公開するために、わずかにあなたのコードを修正し、それをコンパイル&実行可能コードを作っ:

import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 
import jdk.nashorn.api.scripting.AbstractJSObject; 
import java.util.function.Supplier; 

public class Foo extends AbstractJSObject { 
    String bar; 

    public Foo() { 
     super(); 
    } 

    public Foo(String b) { 
     super(); 
     this.bar = b; 
    } 

    @Override 
    public Object newObject(Object... args) { 
     String bar = null; 
     if (args[0] != null) bar = args[0].toString(); 

     Foo f = new Foo(bar); 
     return f; 
    } 

    @Override 
    public Object getMember(String name) { 
     if (name.equals("toString")) { 
      // Returning a lambda function as value of this property. 
      // nashorn code can call lambdas just like script functions! 
      // You may also choose to return another JSObject that 
      // returns true in isFunction() method and implements "call" 
      // as well. 

      return (Supplier<String>)this::toString; 
     } else { 
      // implement other exposed properties here. 
      return null; 
     } 
    } 

    @Override 
    public String toString() { 
     return "Foo: " + this.bar; 
    } 


    public static void main(String[] args) throws Exception { 
     ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 
     engine.put("foo", new Foo()); 

     // f.toString() would call getMember("toString") and the 
     // returning lambda is called! 

     engine.eval("var f = new foo('hi'); print(f.toString());"); 
    } 
} 
+0

ありがとう!あなたがそれを言及した今、それは意味をなさない。文書でこれを説明することがより明確になってほしい。 –

0

あなたはこの方法で試すことができます:

import javax.script.*; 

    import jdk.nashorn.api.scripting.AbstractJSObject; 

    public class Foo extends AbstractJSObject { 
     String bar; 

     public Foo() { 
      super(); 
     } 

     public Foo(String b) { 
      super(); 
      this.bar = b; 
     } 

     @Override 
     public Object newObject(Object... args) { 
      String bar = null; 
      if (args[0] != null) bar = args[0].toString(); 

      Foo f = new Foo(bar); 
      return f; 
     } 

     @Override 
     public String toString() { 
      return "Foo: " + this.bar; 
     } 


     public static void main(String[] args) throws ScriptException { 
      ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); 
      engine.put("foo", new Foo()); 

      Compilable compilable = (Compilable) engine; 
      Bindings bindings = engine.createBindings(); 
      String script = "function add(op1,op2){return op1+op2} add(a, b)"; 
      CompiledScript jsFunction = compilable.compile(script); 
      bindings.put("a", 1);bindings.put("b", 2); //put java object into js runtime environment 
      Object result = jsFunction.eval(bindings); 
      System.out.println(result); 
     } 
    } 
+0

toStringは "new foo( 'bar')のメソッドではないという問題をどのように解決しますか? –

関連する問題