我有一个方法假设应该将类名,参数和方法名作为参数,并根据在哪个类中找到它来调用该方法。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。使用字符串作为参数进行invokExact时,出现com.sun.jdi.InvalidTypeException。所有这些也都在上面的注释中列出。我无法弄清楚我在做什么错。任何帮助将不胜感激!如果代码中缺少它们,请告诉我! (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 通过MethodHandle调用方法通常需要4个步骤:创建一个查找对象MethodHandles.Lookup,该对象将负责创建MethodHandle;实例化一个MethodType,它表示方法句柄接受和返回的参数类和返回类型类;在给定的类上查找带有查找和MethodHandle的MethodType;用一些参数调用MethodHandle。例如,假设您要调用该方法public boolean navigateToUrl(String strUrl) { return true;}位于类FooBar中。public void invokeMethod() throws Throwable { // 1. Retrieves a Lookup MethodHandles.Lookup lookup = MethodHandles.lookup(); // 2. Creates a MethodType MethodType methodType = MethodType.methodType(boolean.class, String.class); // ^-----------^ ^----------^ // return type argument class // 3. Find the MethodHandle MethodHandle handle = lookup.findVirtual(FooBar.class, "navigateToUrl", methodType); // ^----------^ ^-------------^ // | name of method // class from which method is accessed // 4. Invoke the method boolean b = (boolean) handle.invokeExact(fooBar, "test"); // ^----^ ^----^ // | argument // instance of FooBar to invoke the method on System.out.println(b);}这是一个示例代码:您可以检索不同的查找,上面给出的查找将可以访问包括私有方法在内的每种方法。您可以使用publicLookup()将自己限制为可公开访问的方法。通过查找,您不仅可以找到方法,还可以找到字段或构造函数。您可以参考this question(和this one)以获取有关MethodHandle的更多信息。 (adsbygoogle = window.adsbygoogle || []).push({});
08-16 19:08