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
创建可运行文件,可运行文件使用此引用的副本。