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();
添加回答
舉報