简体   繁体   English

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

[英]Assigning object to interface variable without implementing interface

I was just learning about method refernce concept of java 8.What I found strange is the example where a method reference is assigned to the interface variable without implementing the interface, And calling abstract method of interface is calling the method referenced.我刚刚在学习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();
    }
}

Above code prints the message of saySomething method, I am trying to understand how the memory allocation for methods and objects is done here and how overall this works.上面的代码打印了 saySomething 方法的消息,我试图了解方法和对象的内存分配是如何在这里完成的,以及总体上是如何工作的。

Any help appreciated.任何帮助表示赞赏。

This is just a syntactic sugar to an anonymous implementation or a lambda with a closure (referring to a state outside of the definition, in your case the instance of methodReference ).这只是匿名实现或带有闭包的 lambda 的语法糖(指的是定义之外的状态,在您的情况下是methodReference的实例)。 Method references and lambdas are treated equally with that respect.在这方面,方法引用和 lambda 表达式被同等对待。 So the same memory allocation really.所以真的是相同的内存分配。

The use of method references (or lambdas) is possible when an interface has only one non-static method and the signature of that method matches that of the lambda or the method reference.当接口只有一个非静态方法并且该方法的签名与 lambda 或方法引用的签名匹配时,可以使用方法引用(或 lambdas)。 In this case the compiler will know how to wrap it and therefore it will be assignable.在这种情况下,编译器将知道如何包装它,因此它将是可分配的。 It does not matter if it is one of "standard" interfaces such as Function , Consumer or Supplier or a custom one, it should be a functional interface that's all.无论它是FunctionConsumerSupplier等“标准”接口之一,还是自定义接口,它都应该是一个功能接口,仅此而已。

The following is quoted from the official Oracle Java documentation :以下引用Oracle Java 官方文档

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

The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b) .方法引用Person::compareByAge在语义上与 lambda 表达式(a, b) -> Person.compareByAge(a, b) Each has the following characteristics:每个都有以下特点:

  • Its formal parameter list is copied from Comparator.compare, which is (Person, Person).它的形参列表是从 Comparator.compare 复制过来的,即 (Person, Person)。
  • Its body calls the method Person.compareByAge.它的主体调用方法 Person.compareByAge。

While your Sayable does not explicitly declare that it is a @FunctionalInterface , it indeed is one, as it has exactly one non-static method.虽然您的Sayable没有明确声明它是一个@FunctionalInterface ,但它确实是一个,因为它只有一个非静态方法。

Any functional interface can be assigned a lambda-like expression (such as () -> printf("bla bla") ) or a method reference (such as methodReference::saySomething ).任何函数接口都可以分配一个类似 lambda 的表达式(例如() -> printf("bla bla") )或方法引用(例如methodReference::saySomething )。 That's it.就是这样。

   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
    }

    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM