TL;DR
- 「
MethodHandle Aからの戻り値 ->MethodHandle Bの引数」という形の合成は、MethodHandles.filterReturnValueを使えば実現できる
やること
「Method Aを呼び出し、その結果をMethod Bに渡す」というような場合、従来のリフレクションではそれぞれのMethodを個別に呼び出す必要が有りました。
一方、MethodHandleの場合、それぞれのMethodHandleを合成することができます。
これによって呼び出しに関する記述が簡略化します。
また、手元で軽くJMHベンチマークを取った限り、それぞれを個別に呼び出すよりも、合成結果を1回呼び出す方が高速でした。
やり方
MethodHandles.filterReturnValueで実現できます。
以下はJavaDocのサンプルにコメントを補完・整形した疑似コードです。
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; // 文字列を結合するMethodHandle MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); // "x"と"y"を結合すれば"xy"になる System.out.println((String) cat.invokeExact("x", "y")); // xy // 文字列長を取得するMethodHandle MethodHandle length = lookup().findVirtual(String.class, "length", methodType(int.class)); // MethodHandles.filterReturnValueで合成 MethodHandle f0 = filterReturnValue(cat, length); // 「文字列結合 -> 結合結果の文字列長取得」という1つの関数のように振る舞う // "x"と"y"を結合した結果の文字列長は2 System.out.println((int) f0.invokeExact("x", "y")); // 2
補足
引数を変換したいケースでは、filterArgumentsが利用できます。