第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在運(yùn)行時使用 LambdaMetafactory 訪問動態(tài)類中的非靜態(tài)方法

如何在運(yùn)行時使用 LambdaMetafactory 訪問動態(tài)類中的非靜態(tài)方法

蕪湖不蕪 2021-12-30 17:22:54
我正在嘗試使用 LambdaMetafactory 來替換反射,但是我遇到了問題。如果我使用特定的類,那么它運(yùn)行良好,就像這樣:        MethodHandles.Lookup lookup = MethodHandles.lookup();        MethodType type = MethodType.methodType(ResponseMsg.class,Map.class);        MethodHandle mh = lookup.findVirtual(TestService.class,"testMethod",type);        TestService ins = TestService.getInstance();        MethodHandle factory = LambdaMetafactory.metafactory(                lookup, "apply", MethodType.methodType(Function.class,TestService.class),                type.generic(), mh, type).getTarget();        factory.bindTo(ins);        Function lambda = (Function) factory.invokeExact(ins);但是如果我Class<?>用來替換特定的類,那么它就行不通了,就像這樣:    public static Function generateLambda(@NotNull Class<?> cls,@NotNull String method) {    MethodHandles.Lookup lookup = MethodHandles.lookup();    MethodType type = MethodType.methodType(RETURN_TYPE,PARM_TYPE);    try {        MethodHandle mh = lookup.findVirtual(cls,method,type);        Object instance = getInstance(cls);        if(instance == null) {            return null;        }        MethodHandle factory = LambdaMetafactory.metafactory(                lookup, "apply", MethodType.methodType(Function.class,cls),                type.generic(), mh, type).getTarget();        factory.bindTo(cls.cast(instance));        return (Function) factory.invokeExact(cls.cast(instance));    } catch (Throwable e) {        logger.error("get Function fail, cause :" ,e);        return null;    }}這是例外:java.lang.invoke.WrongMethodTypeException: expected (TestService)Function but found (Object)Function    at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:298)    at java.lang.invoke.Invokers.checkExactType(Invokers.java:309)    at com.utils.cache.ClassUtils.generateLambda(ClassUtils.java:182)第 182 行是:return (Function) factory.invokeExact(cls.cast(instance));我知道只使用靜態(tài)方法可以解決這個問題,但我想知道有沒有其他方法可以解決它而無需將非靜態(tài)更改為靜態(tài)。在這個方法中,我使用反射找到Class中的靜態(tài)方法getInstance,并返回一個實(shí)例,它只是一個簡單的單例。
查看完整描述

1 回答

?
侃侃無極

TA貢獻(xiàn)2051條經(jīng)驗(yàn) 獲得超10個贊

問題是你正在使用


factory.bindTo(ins);

Function lambda = (Function) factory.invokeExact(ins);

分別


factory.bindTo(cls.cast(instance));

return (Function) factory.invokeExact(cls.cast(instance));

調(diào)用bindTo會創(chuàng)建一個MethodHandle,其第一個參數(shù)綁定到指定的對象實(shí)例,但是,您忽略了新的MethodHandle. 因此,在調(diào)用未綁定句柄時,您需要再次將實(shí)例指定為參數(shù)。


對于此調(diào)用,編譯時類型很重要。在第一個示例中,參數(shù)的編譯時類型是正確的,因此調(diào)用具有正確的簽名(TestService)Function。


在第二個示例中, 的編譯時類型instance是Object,因此編譯成字節(jié)碼的簽名將是(Object)Function,這不是完全匹配。使用cls.cast(…)無濟(jì)于事,因?yàn)檫@將執(zhí)行運(yùn)行時檢查并斷言泛型類型匹配,如果您在這里使用類型變量,但兩者都與invokeExact調(diào)用的字節(jié)碼無關(guān)。


你有兩個選擇。您可以簡單地使用invoke,它允許在調(diào)用期間進(jìn)行類型轉(zhuǎn)換(犧牲一點(diǎn)性能)


// unused factory.bindTo call omitted

return (Function) factory.invoke(instance); // noneffective cls.cast omitted

或者您更改代碼以執(zhí)行似乎最初打算的操作,請在調(diào)用之前綁定第一個參數(shù):


factory = factory.bindTo(instance);

return (Function)factory.invokeExact();

因?yàn)閷τ陬A(yù)先綁定的方法句柄,不需要參數(shù),您再次有一個精確的調(diào)用(bindTo不是簽名多態(tài)的,因此,只會在運(yùn)行時檢查參數(shù)的類型)。


你也可以把它寫成單行


return (Function)factory.bindTo(instance).invokeExact();


查看完整回答
反對 回復(fù) 2021-12-30
  • 1 回答
  • 0 關(guān)注
  • 172 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號