将对象分配给接口变量而不实现接口

Bru*_*yne 5 java functional-programming interface object

我刚刚在学习java 8的方法引用概念。我发现奇怪的是将方法引用分配给接口变量而不实现接口的示例,而调用接口的抽象方法就是调用引用的方法。

interface Sayable {
    void say();
}

public class InstanceMethodReference {
    public void saySomething() {
        System.out.println("Hello, this is non-static method.");
    }

    public static void main(String[] args) {
        InstanceMethodReference methodReference = new InstanceMethodReference();
        Sayable sayable = methodReference::saySomething;
        sayable.say();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码打印了 saySomething 方法的消息,我试图了解方法和对象的内存分配是如何在这里完成的,以及总体上是如何工作的。

任何帮助表示赞赏。

Ole*_*yar 4

这只是匿名实现或带有闭包的 lambda 的语法糖(指的是定义之外的状态,在您的情况下是methodReference)。在这方面,方法引用和 lambda 被同等对待。所以内存分配确实是一样的。

当接口只有一个非静态方法并且该方法的签名与 lambda 或方法引用的签名匹配时,可以使用方法引用(或 lambda) 。在这种情况下,编译器将知道如何包装它,因此它是可分配的。无论它是“标准”接口之一FunctionConsumer还是Supplier自定义接口,它都应该是一个功能性接口,仅此而已。

以下引用Oracle Java官方文档

Arrays.sort(rosterAsArray, Person::compareByAge);
Run Code Online (Sandbox Code Playgroud)

方法引用Person::compareByAge在语义上与 lambda 表达式相同(a, b) -> Person.compareByAge(a, b)。每个都具有以下特征:

  • 它的形参列表是从Comparator.compare复制过来的,即(Person, Person)。
  • 它的主体调用方法 Person.compareByAge。