Java8中的介面現在支援在宣告方法的同時提供實現,這聽起來讓人驚訝!通過兩種方式可以完成這種操作。其一,Java8允許在介面內宣告靜態方法。其二,Java8引入了一個新功能,叫預設方法。兩個例子就是List介面中的sort,以及Collection介面中的stream。
List介面中的sort方法是Java8中的全新方法,它的定義如下:
default void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
複製程式碼
請注意返回型別之前的新default修飾符。通過它,我們能夠知道一個方法是否為預設方法。這裡的sort方法呼叫了Collections.sort方法進行排序操作。由於有了這個新的方法,我們現在可以直接通過呼叫sort,對列表中的元素進行排序。
List<Integer> numbers = Arrays.asList(3, 5, 1, 2, 6);
numbers.sort(Comparator.naturalOrder());// sort是List介面的預設方法
複製程式碼
不過除此之外,這段程式碼中還有其他的新東西。注意到了嗎,我呼叫了Comparator.naturalOrder()。這是Comparator介面的一個全新的靜態方法,它返回一個Comparator物件,並按自然序列對其中的元素進行排序(即標準的字母數字方式排序)。
Collection中的stream方法的定義如下:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
複製程式碼
簡而言之,向介面新增方法是諸多問題的罪惡之源;一旦介面發生了變化,實現這些介面的類往往也需要更新,提供新新增方法的實現才能適配介面的變化。如果你對介面以及它所有相關的實現有完全的控制,這可能不是個大問題。但是這種情況是極少的。這就是引入預設方法的目的:它讓類可以自動繼承介面的一個預設實現。
靜態方法及介面
同時定義介面以及工具輔助類是Java語言常用的一種模式,工具類定義了介面例項協作的很多靜態方法。比如,Collections就是處理Collection物件的輔助類。由於靜態方法可以存在於介面內部,你程式碼中的這些輔助類就沒有存在的必要,你可以把這些靜態方法轉移到介面內部。為了保持後向的相容性,這些類依然會存在於Java應用程式的介面之中。