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 件のコメント:
コメントを投稿