代码之家  ›  专栏  ›  技术社区  ›  user1870400

如何使用MethodHandles调用在Java8中实现接口的类上的方法?

  •  0
  • user1870400  · 技术社区  · 7 年前
    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

    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
    

    问题:

    1. 如何使用 MethodHandles 调用实现接口的类的方法?
    2. (int)mh.invoke(2, 3) ?
    1 回复  |  直到 7 年前
        1
  •  1
  •   Oleksandr Pyrohov Andreas    7 年前

    您忘了再包含一个参数—一个实例,将在该实例上调用该方法:

    Class<?> barClass = classLoader.loadClass("Bar");
    Object barInstance = barClass.getConstructor().newInstance();
    System.out.println(mh.invoke(barInstance, 2, 3));
    

    另外,返回类型 MethodHandle.invoke Object