1. 程式人生 > >Lambda表達式與函數式接口

Lambda表達式與函數式接口

tar nali 聲明 告訴 ger 信息 功能 程序 默認

Lambda表達式的類型,也被稱為目標類型(targer type),Lambda表達式的目標類型必須是“函數式接口(functional interface)”。函數式接口代表只包含一個抽象方法的接口。函數式接口可以包含多個默認方法、類方法,但只能聲明一個抽象方法。

如果采用匿名內部類的語法來創建函數式接口,則只需要實現一個抽象方法,在這種情況下即可采用Lambda表達式來創建對象。該表達式創建出來的對象的目標類型就是這個函數式接口。

Java 8 專門為函數式接口提供了@FunctionalInterface註解,該註解通常放在接口定義前面,對程序功能沒有任何作用,它用於告訴編譯器執行更嚴格的檢查——檢查該連接口必須是函數式接口,否則編譯器就會報錯。

由於Lambda表達式的結果就是被當成對象,因此程序中完全可以使用Lambda表達式進行賦值,例如:

Runnable r = ()-> {
    for(int i = 0; i < 100; i++){
        //coding here
    }
};

Runnable接口中只包含一個無參數的方法,Lambda表達式代表的匿名方法實現了Runnable接口中唯一的、無參數的方法,因此Lambda表達式創建了一個Runnable對象

Runnable是Java本身提供的一個函數式接口

從上面代碼可以看出,Lambda表達式實現的是匿名方法——因此它只能實現特定函數式接口中的唯一方法。這意味著Lambda表達式有如下兩個限制

  • Lambda表達式的目標類型必須是明確的函數式接口。
  • Lambda表達式只能為函數式接口創建對象。Lambda表達式只能實現一個方法,因此它只能為只有一個抽象方法的接口(函數式接口)創建對象。

如下的代碼會報錯

Object obj = ()-> {
    for(int i = 0; i < 100; i++){
        //coding here
    }
};

這段代碼與上一段幾乎完全相同,只是此時Lambda表達式賦值給Object對象

不兼容的類型:Object不是函數式接口

從該錯誤信息可以看出,Lambda表達式的目標類型必須是明確的函數式接口。上面代碼將Lambda表達式賦值給Object變量,編譯器只能確定該Lambda表達式的類型為Object,而Object並不是函數式接口,因此報錯。

為了保證Lambda表達式的目標類型是一個明確的函數式接口,可以有如下三種常見方式。

  • 將Lambda表達式賦值給函數式接口類型的變量
  • 將Lambda表達式作為函數式接口類型的變量
  • 使用函數式接口對Lambda表啊是進行強制類型轉換
Object obj = (Runnable)()-> {
    for(int i = 0; i < 100; i++){
        //coding here
    }
};

Lambda表達式與函數式接口