Java 8中的函数式接口如何工作

3

在我学习函数式接口概念时,遇到了以下示例。

interface Sayable{  
   void say();  
}  
public class MethodReference {  
    public static void saySomething(){  
        System.out.println("Hello, this is static method.");  
    }  
    public static void main(String[] args) {  
        // Referring static method  
        Sayable sayable = MethodReference::saySomething;  
        // Calling interface method  
        sayable.say();  
    }  
} 

运行时会在输出中打印"Hello, this is static method."。我的问题是,当我们调用未实现的say()方法时,它是如何打印输出的。


5
已经实现。MethodReference::saySomethingSayable接口的一个实例,其say()方法由saySomething方法实现。https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html - JB Nizet
1
我发誓,2014年我第一次看到它时,我有你现在的同样感觉;但是当你阅读更多的文档时,你会习惯的。 - Eugene
1
你只需要相信Java的所有说法。 Sayable 定义为一种类型,一个不接受参数并且不返回任何值的函数,因为Java如此规定。由于 MethodReference :: saySomething 就是这样一种类型的函数,所以可以将它分配给该类型的引用。然后就是你对这种引用的使用方式。有一个随意的方法名称来调用该函数确实很奇怪。但你必须接受它。 - CryptoFool
@JBNizet 和所有人,感谢您接受所给出的答案。 - mallikarjun
2个回答

3
你可以这样理解方法引用:
Sayable sayable = new Sayable() {

    @Override
    void say() {
        // Grab the body of the method referenced by the method reference,
        // which is the following:
        System.out.println("Hello, this is static method.");
    }
}

方法引用是有效的,因为
  • 目标类型是函数接口Sayable(您正在尝试将结果存储到Sayable类型中);并且
  • saySomething()方法引用的签名与函数接口方法say()匹配,即参数返回类型匹配1

Sayable实例的say()方法的实现被称为变量sayable,其等于方法引用所引用的方法的主体。

因此,就像JB Nizet在评论中所说的那样,say()实际上已经被实现了。


1一个小细节:单词“match”并不完全意味着“相等”。例如,如果saySomething()返回一个int,它仍然可以工作,尽管目标类型的唯一方法定义了返回类型为void


0

只有一个抽象方法的接口被称为函数式接口。

如果你想匿名创建接口对象并调用MethodReference的saySomething()方法。通常的方式是这样的...

Sayable sayable = new Sayable() {
  @Override
    void say() {
       MethodReference::saySomething;  
    }
}

在功能接口的情况下,由于始终只有一个方法,您可以忽略 say() 和相关括号——这是由 lambda 提供的。
所以您可以说。
Sayable sayable = MethodReference::saySomething;  

这仅适用于功能接口。不适用于具有多个抽象方法的接口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接