https://blogs.oracle.com/sundararajan/entry/dynamic_linker_api_for_the
JEP 276は、Javaのための動的リンカAPIを定義しています。
JEP 276: Dynamic Linking of Language-Defined Object ModelsこのJEPでは、"プロパティを読み取り"、"プロパティの書き込み "、"callableオブジェクトの呼び出し"といった、invokedynamicのCallsitesと呼ばれる、オブジェクトへのハイレベルな操作をリンクするための機能」を提供します。こうしたプレーンなJavaオブジェクトに対するこうした操作の通常のセマンティクスのためのデフォルトリンカだけでなく、言語固有のリンカのインストールのためのファシリティも提供します。
http://openjdk.java.net/jeps/276
Nashorn JavaScriptエンジンではすでに、プロパティのリンク、インデックスによるアクセス、スクリプトオブジェクトだけでなく、「外部」「ホスト」Javaオブジェクト(POJOs)への呼び出しのためにdynalinkライブラリを使っています。JEP-276を使用し、"jdk,dynalink"と命名されたJava 9モジュールのパブリック(JDK固有の)APIとしてdynalinkを公開します。
現在、"jdk9 sandbox"というOpenJDKリポジトリのJEP-276-branchという名前のブランチに、JEP-276のソースコードがあります。
OpenJDK / jdk9 / sandboxこれは、最終的にjdk9リポジトリに取り込まれます。dynalink" APIで遊んでみたい方は、このフォレストをチェックアウトし、"JEP-276-branch"をビルドすることができます。
http://hg.openjdk.java.net/jdk9/sandbox
Java APIとともに使いたい場合には、最近jshellツールを使っています。
JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)以下はdynalink APIをJavaコードから使うためのjshell REPLのサンプルです。
http://openjdk.java.net/jeps/222
上記のREPLでは、"array size 10" と "list size 2" をそれぞれ表示します。(異なる"this"オブジェクトが渡された場合に)lengthプロパティは自動的に配列の長さに再リンクされ、ArrayListのsize になることに注意してください。Javaオブジェクトのリンク(および再リンク)はdynalink実装に付属する"java beans linker"によって処理されます。import java.lang.invoke.* // dynalink API lives in these packages import jdk.dynalink.* import jdk.dynalink.support.* // dynamic 'operation' for a callsite. 'length' property Operation op = new NamedOperation(StandardOperation.GET_PROPERTY, "length") // method type of operation to be linked - length is 'int' value MethodType mt = MethodType.methodType(int.class, Object.class) // callsite descriptor CallSiteDescriptor desc = new CallSiteDescriptor(MethodHandles.publicLookup(), op, mt) // callsite SimpleRelinkableCallSite cs = new SimpleRelinkableCallSite(desc) // create a linker factory DynamicLinkerFactory fac = new DynamicLinkerFactory() // create dynalink linker DynamicLinker linker = fac.createLinker() // link the callsite linker.link(cs) // invoke it! printf("array size %d\n", (int)cs.getTarget().invoke(new String[10])) import java.util.ArrayList // make a list and populate two elements ArrayList<String> al = new ArrayList<>() al.add("hello") al.add("world") // get 'length' of array list - which is nothing but size printf("list size %d\n", (int)cs.getTarget().invoke(al))
0 件のコメント:
コメントを投稿