亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

解析Java中的默認方法

2019-11-26 15:06:16
字體:
來源:轉載
供稿:網友

 為什么有默認方法?

Java 8 就要來臨,盡管發布期限已經被推遲, 我們仍非常確信在它最終發布的時候會支持lambdas 表達式。 前面提到過,我們之前關于這個主題已經討論了不少,不過,lambdas表達式并不是Java 8中唯一改變的游戲規則。


假設Java 8 已經發布并且包含了lambda?,F在你打算用一下lambda,最明顯的應用場景莫過于對collection的每一個元素應用lambda。
 

List<?> list = …list.forEach(…); // 這就是lambda代碼

在java.util.List或者java.util.Collection接口里都找不到forEach的定義。通常能想到的解決辦法是在JDK里給相關的接口添加新的方法及實現。然而,對于已經發布的版本,是沒法在給接口添加新方法的同時不影響已有的實現。

因此,如果在Java 8里使用lambda的時候,因為向前兼容的原因而不能用于collection庫,那有多糟糕啊。


由于上述原因,引入了一個新的概念。虛擬擴展方法,也即通常說的defender方法, 現在可以將其加入到接口,這樣可以提供聲明的行為的默認實現。

簡單的說,Java的接口現在可以實現方法了。默認方法帶來的好處是可以為接口添加新的默認方法,而不會破壞接口的實現。

在我看來,這并非那種每天都會用到的Java特性,但是它絕對能讓Java的Collections API可以很自然的使用lambda。

最簡單的例子

讓我們看一個最簡單的例子:一個接口A,Clazz類實現了接口A。
 

public interface A {  default void foo(){    System.out.println("Calling A.foo()");  }} public class Clazz implements A {}

代碼是可以編譯的,即使Clazz類并沒有實現foo()方法。在接口A中提供了foo()方法的默認實現。

使用這個例子的客戶端代碼:
 

Clazz clazz = new Clazz();clazz.foo(); // 調用A.foo()

多重繼承?

有一個常見的問題:人們會問 當他們第一次聽到關于默認方法的新的特性時 “如果一個類實現了兩個接口,并且兩個接口都用相同的簽名定義了默認方法,這該怎么辦?”讓我們用先前的例子來展示這個解決方案:
 

public interface A {  default void foo(){    System.out.println("Calling A.foo()");  }} public interface B {  default void foo(){    System.out.println("Calling B.foo()");  }} public class Clazz implements A, B {}

這段代碼不能編譯 有以下原因:

java:class Clazz 從types A到B給foo()繼承了不相關的默認值

為了修復這個,在Clazz里我們不得不手動解決通過重寫沖突的方法:
 

public class Clazz implements A, B {  public void foo(){}}

但是如果我們想從接口A中調用默認實現方法foo(),而不是實現我們自己的方法,該怎么辦呢?這是有可能的,引用A中的foo(),如下所示:
 

public class Clazz implements A, B {  public void foo(){    A.super.foo();  }}

現在我不能十分確信我喜歡這個最終方案。也許它比在簽名里聲明默認方法的實現更為簡練,正如在默認方法規范的第一手稿里所聲明的:
 

public class Clazz implements A, B {  public void foo() default A.foo;}

但是這確實更改了語法,難道不是嗎?它看起來更像一個接口的方法聲明而不是實現。假若接口A和接口B定義了許多相互沖突的默認方法,而我愿意使用所有接口A的默認方法解決沖突,那又如何呢?目前我不得不一個接著一個的解決沖突,改寫每一對沖突的方法。這可能需要大量的工作和書寫大量的模板代碼。

我估計解決沖突的方法需要進行大量的討論,不過看起來創建者決定接受這無法避免的災難。

真實的例子

默認方法實現的真實例子可以在 JDK8早期打的包中找到。回到集合的forEach方法的例子中, 我們可以發現在java.lang.Iterable接口中,它的默認實現如下:
 

@FunctionalInterfacepublic interface Iterable<T> {  Iterator<T> iterator();   default void forEach(Consumer<? super T> action) {    Objects.requireNonNull(action);    for (T t : this) {      action.accept(t);    }  }}

forEach 使用了一個java.util.function.Consumer功能接口類型的參數,它使得我們可以傳入一個lambda表達式或者一個方法引用,如下:
 

List<?> list = …list.forEach(System.out::println);

方法調用
讓我們看一下實際上是如何調用默認的方法的。如果你不熟悉這個問題,那么你可能有興趣閱讀一下Rebel實驗室有關Java字節的報告。

從客戶端代碼的視角來看,默認的方法僅僅是常見的虛擬方法。因此名字應該是虛擬擴展方法。因此對于把默認方法實現為接口的簡單例子類來說,客戶端代碼將在調用默認方法的地方自動調用接口。
 

A clazz = new Clazz();clazz.foo(); // invokeinterface foo() Clazz clazz = new Clazz();clazz.foo(); // invokevirtual foo()

如果默認方法的沖突已經解決,那么當我們修改默認方法并指定調用其中一個接口時候,invokespecial將給我們指定具體調用哪個接口的實現。
 

public class Clazz implements A, B {  public void foo(){    A.super.foo(); // invokespecial foo()  }}

下面是javap的輸出:

public void foo();Code:0: aload_01: invokespecial #2 // InterfaceMethod A.foo:()V4: return

正如你看到的:invokespecial指令用來調用接口方法foo()。從字節碼的視角來看,這仍是新鮮的事情,因為以前你只能通過指向一個類(父類)的而不是指向一個接口的super來調用方法。

最后…

默認方法是對Java語言的有趣補充 亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

色先锋久久影院av| 欧美有码在线观看| 精品久久久久久国产91| 亚洲天堂av在线免费观看| 国产精品久久久久久中文字| 国产精品久久久久7777婷婷| 亚洲在线www| 国产日韩欧美中文| 亚洲天堂一区二区三区| 亚洲精品日韩久久久| 日韩福利伦理影院免费| 日韩经典一区二区三区| 亚洲欧美在线免费观看| 午夜精品在线视频| 国产ts人妖一区二区三区| 亚洲а∨天堂久久精品喷水| 久久777国产线看观看精品| 国产精品国语对白| 欧美大胆在线视频| 91在线观看免费高清| 国产精品久久久久久久久久ktv| 欧美日韩国产黄| 欧美性生交xxxxx久久久| 亚洲第一天堂无码专区| 精品视频一区在线视频| 欧美视频在线观看免费| 国产亚洲综合久久| 久久人人爽国产| 国产日韩中文字幕| 在线观看欧美日韩国产| 国产精品一香蕉国产线看观看| 亚洲精品suv精品一区二区| 日韩高清有码在线| 久久久精品在线| 久久精品中文字幕一区| 亚洲夜晚福利在线观看| 国产日韩欧美另类| 欧美日韩亚洲91| 日韩av影院在线观看| 亚洲aⅴ日韩av电影在线观看| 亚洲第一区在线| 中文字幕亚洲欧美日韩高清| 国产精品999999| 精品高清美女精品国产区| 国产91成人在在线播放| 亚洲人成网站在线播| 国产精品ⅴa在线观看h| 国语自产精品视频在线看抢先版图片| 欧美性色xo影院| 精品国产31久久久久久| 国产精品你懂得| 97精品伊人久久久大香线蕉| 最近中文字幕mv在线一区二区三区四区| 在线看国产精品| 久青草国产97香蕉在线视频| 亚洲欧美成人一区二区在线电影| 久久精品视频亚洲| 国产视频亚洲视频| 97在线日本国产| 国产精品永久在线| 国产精品久久久久久久久借妻| 2019中文字幕在线观看| 海角国产乱辈乱精品视频| 亚洲欧美日韩综合| 欧美巨乳在线观看| 欧美人与性动交a欧美精品| 欧美国产亚洲精品久久久8v| 国产精品网站入口| 91免费欧美精品| 欧美日韩中文在线| 97精品国产97久久久久久春色| 欧美黑人国产人伦爽爽爽| 精品偷拍各种wc美女嘘嘘| 91精品国产综合久久男男| 日韩成人在线免费观看| 国产成人精品久久亚洲高清不卡| 精品久久久久久久久久久| 久久久成人精品| 日韩av在线直播| 国产精国产精品| 久久视频在线免费观看| 北条麻妃久久精品| 日韩成人中文字幕| 亚洲日本中文字幕免费在线不卡| 亚洲性69xxxbbb| 国产精品一区二区三区在线播放| 在线性视频日韩欧美| 亚洲自拍另类欧美丝袜| 欧美丝袜第一区| 国产女人精品视频| 国产在线观看91精品一区| 国产啪精品视频网站| 在线视频欧美日韩| 国产手机视频精品| 26uuu久久噜噜噜噜| zzijzzij亚洲日本成熟少妇| 亚洲二区在线播放视频| 亚洲精品乱码久久久久久按摩观| 欧美在线视频一区| 欧美美女18p| 日韩影视在线观看| 成人免费网视频| 欧美大肥婆大肥bbbbb| 亚洲а∨天堂久久精品9966| 中文字幕精品网| 亚洲第五色综合网| 亚洲国产精久久久久久久| 98精品国产高清在线xxxx天堂| 欧美一区二区.| 国产精品美乳在线观看| 最近2019中文字幕第三页视频| 精品亚洲永久免费精品| 亚洲欧美综合区自拍另类| 欧美成人全部免费| 久久久精品在线观看| 国产精品扒开腿做爽爽爽男男| 久久久久久一区二区三区| 久久久精品视频成人| 亚洲欧美在线磁力| 亚洲精品国产免费| 欧美电影在线免费观看网站| 欧美激情视频一区二区三区不卡| 亚洲欧洲在线视频| 91网站免费看| 亚洲综合中文字幕在线观看| 久久天天躁狠狠躁夜夜躁| 国产精品网站视频| 日韩av在线电影网| 黑人巨大精品欧美一区二区| 5566成人精品视频免费| 亚洲成人av片| 一区二区在线视频播放| 91国产一区在线| 国产精品第一区| 欧美在线视频观看| 欧美国产亚洲精品久久久8v| 日韩欧美福利视频| 91探花福利精品国产自产在线| 91超碰中文字幕久久精品| 亚洲精品免费网站| 亚洲视频电影图片偷拍一区| 欧美成人亚洲成人日韩成人| 亚洲永久在线观看| 欧美孕妇与黑人孕交| 国产欧美最新羞羞视频在线观看| 亚洲欧美日韩爽爽影院| 韩国日本不卡在线| 欧美日韩在线第一页| 综合136福利视频在线| 精品中文字幕乱| 伊人久久久久久久久久久| 久久99亚洲热视| 不卡毛片在线看| 午夜免费久久久久| 亚洲人成网站999久久久综合| 亚洲第一精品夜夜躁人人躁| 日韩免费看的电影电视剧大全| 日韩精品高清在线观看| 欧美精品在线观看| 国产精品成熟老女人| 久久久国产精彩视频美女艺术照福利| zzijzzij亚洲日本成熟少妇| 亚洲图片欧洲图片av| 91在线|亚洲|