我有一個想採取的類名,論證的方法和方法名作爲參數,並調用該方法依賴於它發現它在類中的方法:如何在嘗試調用方法時使用Lambda MetaFactory或方法處理而不是反射?
Method[] methods = className.getDeclaredMethods();
for (Method meth: methods) {
if (meth.getName().equalsIgnoreCase(methodName)) {
try {
MethodType mt = MethodType.methodType(boolean.class, String.class);
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodHandle handle = caller.findVirtual(Utilities.class, meth.getName(), mt);
/*
* Trying to invoke using lambdaMetaFactory
*/
MethodType methodType = MethodType.methodType(boolean.class);
MethodType invokedType = MethodType.methodType(BooleanSupplier.class);
/*
* Throws java.lang.invoke.LambdaConversionException: Incorrect number of parameters for instance method
* invokeVirtual com.grainger.Automation.Utilities.navigateToUrl:(String)boolean; 0 captured parameters,
* 0 functional interface method parameters, 1 implementation parameters
*/
CallSite site = LambdaMetafactory.metafactory(caller, "getAsBoolean", invokedType, methodType, handle, methodType);
MethodHandle factory = site.getTarget();
BooleanSupplier r = (BooleanSupplier) factory.invoke();
System.out.println(r.getAsBoolean());
/*
* Trying to invoke using Method Handle
*/
/*
* Trying to invoke the method handle here, but it fails with:
* java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(Utilities,String)boolean to (Object)Object
* methodArguments is an ArrayList<> that is initialized and populated before
*/
System.out.println(handle.invokeWithArguments(methodArguments.toArray())); //Output B
/*
* Invoking it directly with a string as an argument throws this execption:
* com.sun.jdi.InvalidTypeException: Generated value (java.lang.String) is not compatible with declared type (java.lang.Object[]). occurred invoking method.
*/
System.out.println(handle.invokeExact("www.google.com"));
// keywordResult = (Boolean) handle.invoke("www.google.com");
/*
* Using the regular Reflections API, the method invoke works but is slow
*/
// keywordResult = (Boolean) meth.invoke(classInstance, methodArguments); //Regular refection call to invoke the function
break;
} catch (Throwable e) {
System.out.println(e.getMessage());
keywordResult = false;
}
}
}
我的方法試圖調用位於同一個包內的單獨類中。這是方法的定義:
public boolean navigateToUrl(String strUrl) {
return true;
}
當我嘗試使用lambdametafactory要調用的函數,我得到一個LambdaConversionException。當我嘗試使用方法句柄調用方法時,在使用參數調用併發送ArrayList時出現異常Java.lang.invoke.WrongMethodTypeException>。當以String作爲參數進行invokExact時,我得到一個com.sun.jdi.InvalidTypeException異常。所有這些也都在上面的評論中列出。
我無法弄清楚我在這裏做錯了什麼。任何幫助將不勝感激!如果他們是我從代碼中遺漏的任何東西,請告訴我!
This Works!我相信唯一缺少的就是將類的實例作爲參數傳遞給invokeExact和invokeWithArguments。我是否也可以使用LambdaMetaFactory來完成此操作?性能和代碼運行時間是我需要考慮的事情,在進行我的研究時,我發現Lambdametafactory可以比反射或方法處理快得多。 –
@SahilGupta方法處理將比反射有更多的性能是!'Lambdametafactory'依賴'MethodHandle',所以它是一樣的。 – Tunaki
所以他們沒有太大的區別,我是否使用'Lambdametafactory'和'MethodHandle'?我嘗試使用上面的'lambdametafactory',通過發送'booleanSupplier'函數接口並使用'Methodhandle'來查找函數。你認爲我應該堅持我所擁有的還是嘗試使用「Lambdametafactory」?即使使用「Lambdametafactory」,速度只有一秒,但我更傾向於使用它。 –