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

标签 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() 不同...

所以我的问题是:

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

最佳答案

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

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的方法。

关于Java 8 方法引用 - 仅取消引用一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29040097/

相关文章:

xml - 解码混合对象类型的 xml 数组

enums - Rust-将特征包装在枚举中以用于内存布局和更简单的泛型?

c++ - C++多态中,如何避免函数的名字隐藏(调用错误没有匹配的函数)?

java - Eclipse 崩溃 : "An error has occurred. See the log file"

java - Spark 问题的 GCS 连接器 - 获取存储桶时出错

java - Weblogic 在使用代理时破坏 CXF 证书身份验证

Java - 从字符串(反射)将字段值设置为正确的类型

reflection - 如何对 fsx 文件中的模块进行 typeof?

java - Spring:如何在主bean创建后初始化相关的惰性bean

c# - 创建函数以循环访问 C# 中方法的属性?