public interface Foo {
int add(int x, int y);
}
public class Bar implements Foo {
int add(int x, int y) {
return x+y;
}
}
Теперь представьте, что у меня есть Foo.class и Bar.class в /usr/local.
Ниже приведен класс, который загружает как Bar, так и Foo и хочет динамически вызывать метод add.
import java.io.File;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.URL;
import java.net.URLClassLoader;
public class Test {
public static void main(String... args) throws Throwable {
File classFile = new File("/usr/local");
ClassLoader classLoader = new URLClassLoader(new URL[]{classFile.toURI().toURL()});
Class fooClass = classLoader.loadClass("Foo");
MethodHandle mh = MethodHandles
.lookup()
.findVirtual(fooClass, "add", MethodType.methodType(int.class, int.class, int.class));
System.out.println((int)mh.invoke(2, 3));
}
}
Ниже я получаю ошибку
Exception in thread "main" java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(Foo,int,int)int to (int,int)int
Вопросов:
MethodHandles для вызова метода класса, реализующего интерфейс?(int)mh.invoke(2, 3)?



Вы забыли указать еще один аргумент - экземпляр, на котором будет вызываться метод:
Class<?> barClass = classLoader.loadClass("Bar");
Object barInstance = barClass.getConstructor().newInstance();
System.out.println(mh.invoke(barInstance, 2, 3));
Кроме того, тип возврата MethodHandle.invoke - Object, поэтому в этом случае вы не можете избежать приведения.