成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 8 有多牛?打破一切你對(duì)接口的認(rèn)知!

開(kāi)發(fā) 后端
前段時(shí)間面試了一個(gè) 39 歲的程序員,結(jié)果不是很理想,沒(méi)看過(guò)的點(diǎn)擊這里閱讀。最近也面試一些 Java 程序員,不乏工作 4、5 年經(jīng)驗(yàn)的,當(dāng)我問(wèn)他一些 Java 8 的新特性時(shí),大多卻答不上來(lái)。

 [[346200]]

前段時(shí)間面試了一個(gè) 39 歲的程序員,結(jié)果不是很理想,沒(méi)看過(guò)的點(diǎn)擊這里閱讀。

最近也面試一些 Java 程序員,不乏工作 4、5 年經(jīng)驗(yàn)的,當(dāng)我問(wèn)他一些 Java 8 的新特性時(shí),大多卻答不上來(lái)。

比如下面這道題:

棧長(zhǎng):接口里面可以寫(xiě)方法嗎?

小A:當(dāng)然可以啊,默認(rèn)就是抽象方法。

棧長(zhǎng):那接口里面可以寫(xiě)實(shí)現(xiàn)方法嗎?

小A:不可以,所有方法必須是抽象的。

棧長(zhǎng):你確定嗎?

小A:確定……

小A看起來(lái)對(duì)我的問(wèn)題有點(diǎn)懷疑人生,心里肯定估摸著,我不會(huì)在給他埋了什么坑吧。然后他還是仔細(xì)再想了一下,最后還是斬釘截鐵的告訴我:接口里面只能寫(xiě)抽象方法,不能寫(xiě)實(shí)現(xiàn)方法。

棧長(zhǎng):接口里面是可以寫(xiě)實(shí)現(xiàn)方法的,Java 8 開(kāi)始就可以了,你用過(guò) Java 8 嗎?

小A:好吧,看來(lái)是我學(xué)藝不精,Java 8 有了解一點(diǎn),比如那個(gè) Lambda 表達(dá)式,但實(shí)際項(xiàng)目中也沒(méi)怎么用。

通過(guò)和小A的交流,我也看到了許多開(kāi)發(fā)者的問(wèn)題,雖然開(kāi)發(fā)版本用的是 Java 8,但實(shí)際用的還是 Java 8 之前的最基礎(chǔ)的語(yǔ)法,對(duì) Java 8 新增的特性一無(wú)所知。

Java 8 至 2014 年發(fā)布至今,已經(jīng)過(guò)了 6 個(gè)年頭了,最新的 Java 14 都發(fā)布了,OK,這個(gè)不在本篇討論范圍之內(nèi), Java 8+ 系列教程請(qǐng)關(guān)注公眾號(hào)Java技術(shù)?;貜?fù) "java" 進(jìn)行閱讀,本篇就是想順著問(wèn)小A的這個(gè)問(wèn)題展開(kāi)。

什么是默認(rèn)方法和靜態(tài)方法?

上面也說(shuō)了,Java 8 開(kāi)始是可以有方法實(shí)現(xiàn)的,可以在接口中添加默認(rèn)方法和靜態(tài)方法。

默認(rèn)方法用 default 修飾,只能用在接口中,靜態(tài)方法用 static 修飾,這個(gè)我們不陌生了。并且接口中的默認(rèn)方法、靜態(tài)方法可以同時(shí)有多個(gè)。

在接口中寫(xiě)實(shí)現(xiàn)方法一點(diǎn)也不稀奇,像這樣的用法,從 Java 8 到 Java 14 已是遍地開(kāi)花,到處都可以看到接口默認(rèn)方法和靜態(tài)方法的身影。

比如我們來(lái)看下在 JDK API 中 java.util.Map 關(guān)于接口默認(rèn)方法和靜態(tài)方法的應(yīng)用。

  1. /* 
  2. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  3. */ 
  4. public interface Map<K,V> { 
  5.  
  6.     ... 
  7.      
  8.     /** 
  9.     * 接口默認(rèn)方法 
  10.     */ 
  11.     default boolean remove(Object key, Object value) { 
  12.         Object curValue = get(key); 
  13.         if (!Objects.equals(curValue, value) || 
  14.             (curValue == null && !containsKey(key))) { 
  15.             return false
  16.         } 
  17.         remove(key); 
  18.         return true
  19.     } 
  20.      
  21.     ... 
  22.      
  23.     /** 
  24.     * 接口靜態(tài)方法 
  25.     */ 
  26.     public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() { 
  27.         return (Comparator<Map.Entry<K, V>> & Serializable
  28.             (c1, c2) -> c1.getKey().compareTo(c2.getKey()); 
  29.     } 
  30.      
  31.     ... 
  32.      
  33. }     

為什么要有接口默認(rèn)方法?

舉一個(gè)很現(xiàn)實(shí)的例子:

我們的接口老早就寫(xiě)好了,后面因?yàn)楦鞣N業(yè)務(wù)問(wèn)題,避免不了要修改接口。

在 Java 8 之前,比如要在一個(gè)接口中添加一個(gè)抽象方法,那所有的接口實(shí)現(xiàn)類(lèi)都要去實(shí)現(xiàn)這個(gè)方法,不然就會(huì)編譯錯(cuò)誤,而某些實(shí)現(xiàn)類(lèi)根本就不需要實(shí)現(xiàn)這個(gè)方法也被迫要寫(xiě)一個(gè)空實(shí)現(xiàn),改動(dòng)會(huì)非常大。

所以,接口默認(rèn)方法就是為了解決這個(gè)問(wèn)題,只要在一個(gè)接口添加了一個(gè)默認(rèn)方法,所有的實(shí)現(xiàn)類(lèi)就自動(dòng)繼承,不需要改動(dòng)任何實(shí)現(xiàn)類(lèi),也不會(huì)影響業(yè)務(wù),爽歪歪。

另外,接口默認(rèn)方法可以被接口實(shí)現(xiàn)類(lèi)重寫(xiě)。

為什么要有接口靜態(tài)方法?

接口靜態(tài)方法和默認(rèn)方法類(lèi)似,只是接口靜態(tài)方法不可以被接口實(shí)現(xiàn)類(lèi)重寫(xiě)。

接口靜態(tài)方法只可以直接通過(guò)靜態(tài)方法所在的 接口名.靜態(tài)方法名 來(lái)調(diào)用。

接口默認(rèn)方法多繼承沖突問(wèn)題

因?yàn)榻涌谀J(rèn)方法可以被繼承并重寫(xiě),如果繼承的多個(gè)接口都存在相同的默認(rèn)方法,那就存在沖突問(wèn)題。

下面我會(huì)列舉 3 個(gè)沖突示例場(chǎng)景。

沖突一

來(lái)看下面這段程序:

  1. /* 
  2. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  3. */ 
  4. interface People { 
  5.  default void eat(){ 
  6.   System.out.println("人吃飯"); 
  7.  } 
  8.  
  9. /* 
  10. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  11. */ 
  12. interface Man { 
  13.  default void eat(){ 
  14.   System.out.println("男人吃飯"); 
  15.  } 
  16.  
  17. /* 
  18. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  19. */ 
  20. interface Boy extends Man, People { 
  21.  

Boy 同時(shí)繼承了 People 和 Man,此時(shí)在 IDEA 編輯器中就會(huì)報(bào)錯(cuò):

 

這就是接口多繼承帶來(lái)的沖突問(wèn)題,Boy 不知道該繼承誰(shuí)的,這顯然也是個(gè)問(wèn)題,IDEA 也會(huì)提示,需要重寫(xiě)這個(gè)方法才能解決問(wèn)題:

  1. /* 
  2. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  3. */ 
  4. interface Boy extends Man, People { 
  5.  
  6.  @Override 
  7.  default void eat() { 
  8.   System.out.println("男孩吃飯"); 
  9.  } 

在方法里面還能直接調(diào)用指定父接口的默認(rèn)方法,比如:

  1. /* 
  2. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  3. */ 
  4. interface Boy extends Man, People { 
  5.  
  6.  @Override 
  7.  default void eat() { 
  8.   People.super.eat(); 
  9.   Man.super.eat(); 
  10.   System.out.println("男孩吃飯"); 
  11.  } 

再加個(gè)實(shí)現(xiàn)類(lèi)測(cè)試一下:

  1. /* 
  2. * 來(lái)源公眾號(hào):Java技術(shù)棧  
  3. */ 
  4. static class Student implements Boy { 
  5.  
  6.  public static void main(String[] args) { 
  7.   Student student = new Student(); 
  8.   student.eat(); 
  9.  } 
  10.  

輸出:

  1. 人吃飯 
  2. 男人吃飯 
  3. 男孩吃飯 

嗯,很強(qiáng)大!

沖突二

我們?cè)贀Q一種寫(xiě)法,把 Man 繼承 People,然后 Man 重寫(xiě) People 中的默認(rèn)方法。

 

此時(shí),編輯器不報(bào)錯(cuò)了,而 People 的默認(rèn)方法置灰了,提示沒(méi)有被用到。

再運(yùn)行一下上面的示例,輸出:

男人吃飯

因?yàn)?Man 繼承 People,Man 又重定了默認(rèn)方法。很顯然,這個(gè)時(shí)候,Boy 知道該繼承誰(shuí)的默認(rèn)方法了。

沖突三

在 Man 接口中新增一個(gè)方法:say,然后在 Boy 接口中新增一個(gè)默認(rèn)方法:say。

 

這時(shí)候,Man 中的抽象方法居然被忽略了,IDEA 都提示說(shuō)沒(méi)用到,這顯然是默認(rèn)方法優(yōu)先于抽象方法。

總結(jié)

本文介紹了 Java 8 的默認(rèn)方法和靜態(tài)方法,以及默認(rèn)方法的沖突問(wèn)題解決方案。所以,大家出去面試時(shí),再也不要說(shuō)接口不能寫(xiě)實(shí)現(xiàn)方法了,那就太 OUT 了。。

文中只舉了 3 個(gè)默認(rèn)方法的沖突場(chǎng)景,不確定還沒(méi)有更多沖突問(wèn)題。默認(rèn)方法雖然解決了接口變動(dòng)帶來(lái)的問(wèn)題,但如果設(shè)計(jì)不當(dāng),或者過(guò)度設(shè)計(jì),其帶來(lái)的方法沖突問(wèn)題也是需要引起注意的。

本文轉(zhuǎn)載自微信公眾號(hào)「 Java技術(shù)棧」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系 Java技術(shù)棧公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)棧
相關(guān)推薦

2022-07-15 14:58:26

數(shù)據(jù)分析人工智能IT

2014-11-21 10:25:26

2023-02-10 08:44:05

KafkaLinkedIn模式

2011-11-30 09:28:37

iCloud信息圖云計(jì)算

2021-08-09 14:40:02

物聯(lián)網(wǎng)IOT智能家居

2012-12-31 11:22:58

開(kāi)源開(kāi)放

2020-09-11 10:55:10

useState組件前端

2025-04-11 08:42:10

Java對(duì)象TLAB

2018-06-15 23:00:56

2021-10-05 21:03:54

BeautifulSo 爬蟲(chóng)

2022-04-24 09:00:00

滲透測(cè)試安全數(shù)字時(shí)代

2022-12-30 11:24:21

2014-08-25 11:22:30

2023-09-11 07:36:35

2020-05-12 10:43:24

物聯(lián)網(wǎng)數(shù)據(jù)技術(shù)

2023-05-28 18:21:32

2022-07-06 10:07:21

物聯(lián)網(wǎng)IoT

2022-09-01 15:26:45

物聯(lián)網(wǎng)人工智能傳感器

2020-04-21 14:49:35

物聯(lián)網(wǎng)數(shù)據(jù)技術(shù)

2022-08-27 12:15:51

Linux Mint操作系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩精品一区二区三区中文在线 | 国产精品一区二区av | 91精品国产乱码久久久 | 成人免费大片黄在线播放 | 久久精品国产久精国产 | 欧美色综合 | 日韩欧美在线播放 | 亚洲一区二区视频在线观看 | 一级做a爰片性色毛片 | 中文字幕日韩欧美一区二区三区 | 国产精品一区在线观看 | 性色av一区二区三区 | 色av一区二区| 亚洲第一成人影院 | 免费视频二区 | 成人免费视频网址 | 亚洲国产成人av | 久久性av | 国产97色| 久久精品国产a三级三级三级 | 久久一区二区三区免费 | 亚洲一区国产精品 | 久久久久一区二区三区四区 | 免费影视在线观看 | 久久99视频| 亚洲欧美一区二区三区1000 | 精品国产欧美 | 欧美精品v国产精品v日韩精品 | 亚洲一区 中文字幕 | 中文无吗 | 日韩一级免费电影 | 国产一区二区三区在线 | 亚洲视频在线观看 | 欧美久久久久 | 欧美精品久久久久久久久老牛影院 | 久久av.com | 高清成人免费视频 | wwww.xxxx免费 | 亚洲成人动漫在线观看 | 青娱乐一区二区 | 国产福利资源在线 |