以下の内容はhttps://wrongwrong163377.hatenablog.com/entry/2025/05/10/220837より取得しました。


【Java】MethodHandleを合成する

TL;DR

  • MethodHandle Aからの戻り値 -> MethodHandle Bの引数」という形の合成は、MethodHandles.filterReturnValueを使えば実現できる

docs.oracle.com

やること

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が利用できます。

docs.oracle.com




以上の内容はhttps://wrongwrong163377.hatenablog.com/entry/2025/05/10/220837より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14