[JavaScript, Java] Dynamic linker API for the Java platform (JEP 276)

原文はこちら。
https://blogs.oracle.com/sundararajan/entry/dynamic_linker_api_for_the


JEP 276は、Javaのための動的リンカAPIを定義しています。
JEP 276: Dynamic Linking of Language-Defined Object Models
http://openjdk.java.net/jeps/276 
このJEPでは、"プロパティを読み取り"、"プロパティの書き込み "、"callableオブジェクトの呼び出し"といった、invokedynamicのCallsitesと呼ばれる、オブジェクトへのハイレベルな操作をリンクするための機能」を提供します。こうしたプレーンなJavaオブジェクトに対するこうした操作の通常のセマンティクスのためのデフォルトリンカだけでなく、言語固有のリンカのインストールのためのファシリティも提供します。

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
http://hg.openjdk.java.net/jdk9/sandbox 
これは、最終的にjdk9リポジトリに取り込まれます。dynalink" APIで遊んでみたい方は、このフォレストをチェックアウトし、"JEP-276-branch"をビルドすることができます。
Java APIとともに使いたい場合には、最近jshellツールを使っています。
JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
http://openjdk.java.net/jeps/222 
以下はdynalink APIをJavaコードから使うためのjshell REPLのサンプルです。
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))
上記のREPLでは、"array size 10" と "list size 2" をそれぞれ表示します。(異なる"this"オブジェクトが渡された場合に)lengthプロパティは自動的に配列の長さに再リンクされ、ArrayListのsize になることに注意してください。Javaオブジェクトのリンク(および再リンク)はdynalink実装に付属する"java beans linker"によって処理されます。

0 件のコメント:

コメントを投稿