簡體   English   中英

MethodHandle 強制轉換返回類型

[英]MethodHandle cast return type

我嘗試通過方法句柄將方法鏈接在一起,其中一些來自泛型類型。 如果 function 返回泛型類型,我必須為 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));
}

您當前的代碼對我來說看起來不錯,您只需要在調用站點使用演員表:

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));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM