Java 8方法引用 - 仅解除引用一次?

时间:2015-03-13 19:06:36

标签: java reflection polymorphism method-reference

我对方法引用感到困惑。请考虑以下脚本。

public class Main {

    static interface I {
        void m();
    }

    static class A implements I {
        @Override
        public void m() {
            System.out.println("A");
        }
    }

    static class B implements I {
        @Override
        public void m() {
            System.out.println("B");
        }
    }

    public static void main(String[] args) {
        A a = new A(); B b = new B();
        I i; Runnable r;
        i = a;
        r = i::m;  // static reference? might infere class
        r.run(); // prints "A"
        run(i); // also prints "A"
        i = b;
        r.run(); // prints "A" instead of "B"!
        run(i); // prints "B"
        r = i::m;
        r.run(); // now prints "B"
        run(i); // also prints "B"
    }

    public static void run(I i) {
        Runnable r = i::m; // dynamic reference, cannot infere class
        r.run();
    }
}

所以看来:

  • 编译器无法内联方法引用,因为它们是多态的。它们在编译时未解析,但在运行时
  • i::m的行为不像i.m() ...

所以我的问题是:

使用反射进行方法参考?为什么他们只做

1 个答案:

答案 0 :(得分:2)

如果你考虑如何在没有方法引用的情况下编写代码,但是使用类和对象,这一切都有意义:

r = i::m;

基本等同于

private class IRunnable implements Runnable {
    private I i;

    public IRunnable(I i) {
        this.i = i;
    }

    @Override
    public void run() {
        i.m();
    }
}

Runnable r = new IRunnable(i);

因此,如果在构造IRunnable之后为i分配另一个值,则IRunnable会继续引用之前的值,并再次调用其run()方法仍将调用之前的i方法。