【问题标题】:MethodHandle cast return typeMethodHandle 强制转换返回类型
【发布时间】:2021-07-30 09:48:23
【问题描述】:

我尝试通过方法句柄将方法链接在一起,其中一些来自泛型类型。如果一个函数返回一个泛型类型,我必须为 MethodType 指定 Object.class,但我看不到将它转换回泛型类型参数类型的简单方法。在大多数情况下,这没有问题,因为invoke 似乎会自动转换它们,但我必须创建可以使用invokeExact 运行的mhs。没有简单的方法来使用方法句柄进行转换吗?

我的测试代码:

public static void main(String[] args) throws Throwable {
    class Prefixer {
        public static String prefix(String s) {
            return "Number: " + s;
        }
    }
    IntFunction<String> converter = Integer::toString;

    var lookup = MethodHandles.lookup();
    var prefixMH = lookup.findStatic(Prefixer.class, "prefix", MethodType.methodType(String.class, String.class));

    var converterMH = lookup.findVirtual(IntFunction.class, "apply", MethodType.methodType(Object.class, int.class));
    converterMH = converterMH.bindTo(converter);

    /* Doesn't work because converter is a (int)Object and no (int)String
    var mh = MethodHandles.filterArguments(prefixMH, 0, converterMH);
     */

    /* Does work for invoke but not for invokeExact
    var prefixCasted = MethodHandles.explicitCastArguments(prefixMH, MethodType.methodType(String.class, Object.class));
    var mh = MethodHandles.filterArguments(prefixCasted, 0, converterMH);
    */
    /* Does work for invoke but not for invokeExact */
    var mh = MethodHandles.filterArguments(prefixMH, 0, converterMH.asType(MethodType.methodType(String.class, int.class)));

    System.out.println(mh.invoke(12));
    System.out.println(mh.invokeExact(42));
}

【问题讨论】:

    标签: java methodhandle


    【解决方案1】:

    您当前的代码对我来说看起来不错,您只需要在调用站点也使用强制转换:

    System.out.println((String) mh.invokeExact(42));
    

    否则调用站点的类型将是 (int)Object,它与 MethodHandle (int)String 的类型不匹配,您将获得 WMTE。

    invoke 版本的呼叫:

    System.out.println(mh.invoke(12));
    

    将使用asType 调用将mh 的类型隐式转换为(int)Object(调用站点的类型),然后调用生成的方法句柄。

    如果您想明确地这样做并使用invokeExact,您可以这样做:

    mh = mh.asType(MethodType.methodType(Object.class, int.class));
    System.out.println(mh.invokeExact(42));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 2019-10-31
      相关资源
      最近更新 更多