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

时间:2018-05-16 09:56:19

标签: java object interface functional-programming

我刚刚学习了java 8的方法引用概念。我发现奇怪的是在没有实现接口的情况下将方法引用分配给接口变量的示例,并且调用接口的抽象方法是调用引用的方法。 / p>

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

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

任何帮助表示感谢。

3 个答案:

答案 0 :(得分:4)

这只是匿名实现的语法糖或带闭包的lambda(指定义之外的状态,在您的情况下是methodReference的实例)。方法参考和lambdas在这方面同等对待。所以真的是相同的内存分配。

当接口只有一个非静态方法并且该方法的签名与lambda或方法引用的签名匹配时,可以使用方法引用(或lambdas)。在这种情况下,编译器将知道如何包装它,因此它将是可分配的。它是否是标准"之一并不重要。 FunctionConsumerSupplier等界面或自定义界面应该是一个功能性界面。

以下是来自official Oracle Java documentation引用

Arrays.sort(rosterAsArray, Person::compareByAge);

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

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

答案 1 :(得分:2)

虽然Sayable没有明确声明它是@FunctionalInterface,但它确实是一个,因为它只有一个非静态方法。

可以为任何功能接口分配类似lambda的表达式(例如() -> printf("bla bla"))或方法引用(例如methodReference::saySomething)。就是这样。

答案 2 :(得分:0)

   interface Rideable {
CarRide getCarRide(String name);
}
class CarRide {
private String name;
public CarRide(String name) {
this.name = name;
}
}

public class Test_QN_26 {

    public static final int MIN = 1;

    public static void main(String[] args) {

    
        //C. (Only one correct):
        Rideable rider = CarRide::new;
        CarRide vehicle = rider.getCarRide("MyCarRide");
        System.out.println("vehicle.toString() "+ vehicle.toString());
    
        

    enter code here
    }

    
}