JDK8學習筆記(二)深識lambda表示式
通過上一篇JDK8學習筆記(一)初識lambda表示式 我們jdk8中的lambda表示式有一一個初步認識,這一篇文章是對lambda表示式的一些細節再做些學習。現在我們可以知道,lambda表示式是替換函式式接口出現的地方,是把一個行為引數化了,或者說方法的某個引數(這個引數是函式式介面)傳遞了一個行為,是一種更加簡潔易懂的寫法。
本篇文章再介紹一些其他關於lambda表示式的其他概念和細節,比如函式描述符,方法引用、lambda表示式是如何型別檢查的?lambda表示式型別推斷,複合lambda表示式的寫法。
1、函式描述符
函式式介面的抽象方法的簽名基本上就是Lambda表示式的簽名。我們將這種抽象方法叫作函式描述符。例如,Runnable介面可以看作一個什麼也不接受什麼也不返回(void)的函式的簽名,因為它只有一個叫作run的抽象方法,這個方法什麼也不接受,什麼也不返回(void)。
函式描述符也叫lambda表示式簽名
這個Runnable介面的函式描述符就是:()-> void 。還有其他的函式式介面的描述符如下:
Predicate<T> T->boolean
Consumer<T> T->void
Function<T,R> T->R
2、lambda表示式的型別檢查、型別推斷
型別檢查過程可以分解為如下所示:
首先,你要找出filter方法的宣告。
第二,要求它是Predicate<Apple>(目標型別)物件的第二個正式引數。
第三,Predicate<Apple>是一個函式式介面,定義了一個叫作test的抽象方法。
第四,test方法描述了一個函式描述符,它可以接受一個Apple,並返回一個boolean。
最後,filter的任何實際引數都必須匹配這個要求。
這段程式碼是有效的,因為我們所傳遞的Lambda表示式也同樣接受Apple為引數,並返回一個boolean。請注意,如果Lambda表示式丟擲一個異常,那麼抽象方法所宣告的throws語句也必須與之匹配。
同一個Lambda表示式就可以與不同的函式式介面聯絡起來,只要它們的抽象方法簽名能夠相容。比如,前面提到的Callable和PrivilegedAction,這兩個介面都代表著什麼也不接受且返回一個泛型T的函式。
特殊void相容規則的例子:
// Predicate返回了一個boolean
Predicate<String> p = s -> list.add(s);
// Consumer返回了一個void
Consumer<String> b = s -> list.add(s);
3、方法引用