java8之lambda表達式(方法引用)

有些時候,你想要傳遞給其餘代碼的操做已經有實現的方法了。示例:java

button.setOnAction(event -> System.out.println(event));

若是你可以只將println方法傳遞給setOnAction方法,就更好了!下面是改後的代碼:ide

button.setOnAction(System.out::println);

表達式System.out::println是一個方法引用,等同於lambda表達式:函數

x -> System.out.println(x)

正如示例代碼所示:操做符將方法名和對象或類的名字分開來。如下三種主要的使用狀況:this

  • 對象::實例方法spa

  • 類::靜態方法code

  • 類::實例方法對象

在前兩種狀況中,方法引用等同於提供方法參數的lambda表達式。如以前所述,System.out::println等同於 System.out.println(x)。類似的,Math::pow等同於(x,y) -> Math.pow(x,y)。在第三種狀況中,第一個參數會成爲執行方法的對象。例如String::compareToIgnoreCase等同於(x,y) -> x.compareToIgnoreCase(y)。接口

注意:若是有多個同名的重載方法,編譯器會試圖從上下文中找到最匹配的一個方法。例如,有兩個版本的Math.max方法,一個接收整型做爲參數,而另外一個接收double類型的值。究竟會選擇哪個方法,取決於Math::max被轉換爲的函數式接口的方法參數。同lambda表達式相似,方法引用也不會獨立存在,它們常常被用於轉換爲函數式接口的實例。編譯器

你還能夠捕獲方法引用中的this參數。例如,this::equals就等同於x -> this.equals(x)。你也能夠使用super對象,如:super::實例方法。示例:io

package java8;

public class J2 {
    public static void main(String[] args) {
        Greeter g = new ConcurrentGreeter();
        g.greet();
    }
}
class Greeter {
    public void greet(){
        System.out.println("Hello world!");
    }
}
class ConcurrentGreeter extends Greeter{
    @Override
    public void greet() {
        //super表明當前類的對象的父類對象,並非函數式接口的父實例對象
        Thread t = new Thread(super::greet);
        t.start();
    }
}
package java8;

public class J3 {
    public static void main(String[] args) {
        Greeter1 g = new Greeter1();
        g.greet();
    }
}
class Greeter1 {
    public void greet() {
        //this表明的當前類的對象,並非函數式接口的實例對象
        Thread t = new Thread(this::printInfo);
        t.start();
    }
    public void printInfo(){
        System.out.println("test success!!");
    }
}
相關文章
相關標籤/搜索