Java 8方法引用-仅取消引用一次?

Java 8方法引用-仅取消引用一次?,java,reflection,polymorphism,method-reference,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 implemen

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

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()
因此,我的问题是:


方法引用是否使用反射?为什么它们只做了一次呢?

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

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);

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

是,这是有意义的。但您必须同意这一点,因为这个特性现在是Java多态性的一个例外。(它们是多态的,但只有一次)。这一点也不例外。Java总是按值传递引用,方法引用也不例外。您正在从
i
创建可运行文件,可运行文件使用此引用的副本。