(rontolisp) docs
← 関数

java:proxy

(java:proxy "fully.qualified.Interface" callable)

rontolisp の callable を背後に持つ、指定インターフェースのホストインスタンスを生成します。各インターフェースメソッドは (callable "method-name" arg...) として callable に振り分けられます。つまり callable の第 1 引数には呼び出されたメソッドの名前(文字列)が渡され、残りの引数がそのメソッドの実引数になります。callable の戻り値はメソッドの戻り型へマーシャリングされます (void メソッドは無視します)。これにより rontolisp のラムダが Java のリスナーやコンパレータになります。単一メソッド (SAM) インターフェースではメソッド名は常に同じなので、慣習的に無視します (下記の例の method 引数)。JVM 専用の java 連携パッケージの一部であり、インタプリタと JVM クラスへのコンパイルの両方で利用できます (WASM バックエンドでは利用できません)。Java 連携ガイドを参照してください。

java.util.function.Supplier をラムダで実装し、その get メソッドを呼ぶとラムダが実行されて 42 を返します。

関数型インターフェース

java.util.function 系を含め、任意のインターフェースで動作します。ラムダの第 1 引数はメソッド名を受け取り、残りの引数がメソッド引数を受け取ります。インターフェースの単一抽象メソッド (SAM) のアリティに合わせてください。

インターフェースSAMラムダの形
Supplierget()(lambda (method) ...)
Functionapply(x)(lambda (method x) ...)
Consumeraccept(x)(lambda (method x) ...)
Predicatetest(x)(lambda (method x) ...)
BiFunctionapply(a, b)(lambda (method a b) ...)
BinaryOperatorapply(a, b)(lambda (method a b) ...)
Comparatorcompare(a, b)(lambda (method a b) ...)

JDK 側が SAM メソッドを呼び出す場合でもプロキシは動作します。たとえば HashMap.merge は、渡された BiFunction を呼び出して古い値と新しい値を合成します。

デフォルトメソッド

動的プロキシは BiFunction.andThenPredicate.and といったデフォルトメソッドも含め、すべてのメソッド呼び出しを callable に転送します。これらを呼ぶと、インターフェース本来のデフォルト実装を実行する代わりに (callable "andThen" ...) としてラムダに振り分けられるため、(f.andThen g) のようなコンビネータは利用できません。代わりに単一抽象メソッド (apply/test/accept/get/compare) を呼んでください。