Java1.8 預設方法
Java8中引入的預設方法,充分展示了Java平臺概念的一致性與JDK向前相容之間的矛盾,而且以犧牲概念的一致性而滿足JDK向前相容。
1.理想與現實
【曾經】Java介面純粹是契約的集合,是一種程式設計的表達方式。從資料抽象的角度看,能夠在不定義class的同時又可以定義type,將是程式設計中強大而有用的機制。Java介面就是這些純粹的介面組成的資料抽象。Java介面只能夠擁有抽象方法,它不涉及任何實現,也不能建立其物件(這一點和抽象類一致)。
多重繼承模型導致額外的複雜性,其中最著名的是鑽石問題或者叫“討嫌的菱形派生”(Dreadful Diamond onDerivation、DDD)。為什麼Java介面能夠避免多繼承的複雜性,關鍵在於它僅僅包含abstract方法。然而從設計的角度看,Java介面放棄了多繼承的內在/固有目標,而顯得是一個權宜之計。
【現在】Java8之前,介面不能升級。因為在介面中新增一個方法,會導致老版本介面的所有實現類的中斷。λ表示式作為核心出現,為了配合λ表示式,JDK中Collection庫需要新增新的方法,如forEach(),stream()等,於是引入了預設方法(defender methods,Virtual extension methods)。它是庫/框架設計的程式設計師的後悔藥。對於以前的遺留程式碼,大家都不知道有這個新方法,既不會呼叫,也不會去實現,如同不存在;編寫新程式碼的程式設計師可以將它視為保底的方法體。型別層次中任何符合override規則的方法,優先於預設方法,因為遺留程式碼可能正好有同樣的方法存在。
預設方法,理論上抹殺了Java介面與抽象類的本質區別——前者是契約的集合,後者是介面與實現的結合體。當然,語法上兩者的差別和以前一樣。這就需要程式設計師來自覺維護兩者的本質區別,把預設方法作為庫、框架向前相容的手段。
預設方法的一個好處:多繼承的著名的是鑽石問題(The Diamond Problem )再次需要關注。因而使以前某些人認為的“為了解決多繼承問題而引入介面機制”的說法變成明顯的錯誤——以前也是錯誤的認識。
有關java1.8 的詳細說明參考 http://lucida.me/blog/java-8-lambdas-insideout-language-features/