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

Java 8 有多牛?打破一切你對接口的認知!

開發 后端
前段時間面試了一個 39 歲的程序員,結果不是很理想,沒看過的點擊這里閱讀。最近也面試一些 Java 程序員,不乏工作 4、5 年經驗的,當我問他一些 Java 8 的新特性時,大多卻答不上來。

 [[346200]]

前段時間面試了一個 39 歲的程序員,結果不是很理想,沒看過的點擊這里閱讀。

最近也面試一些 Java 程序員,不乏工作 4、5 年經驗的,當我問他一些 Java 8 的新特性時,大多卻答不上來。

比如下面這道題:

棧長:接口里面可以寫方法嗎?

小A:當然可以啊,默認就是抽象方法。

棧長:那接口里面可以寫實現方法嗎?

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

棧長:你確定嗎?

小A:確定……

小A看起來對我的問題有點懷疑人生,心里肯定估摸著,我不會在給他埋了什么坑吧。然后他還是仔細再想了一下,最后還是斬釘截鐵的告訴我:接口里面只能寫抽象方法,不能寫實現方法。

棧長:接口里面是可以寫實現方法的,Java 8 開始就可以了,你用過 Java 8 嗎?

小A:好吧,看來是我學藝不精,Java 8 有了解一點,比如那個 Lambda 表達式,但實際項目中也沒怎么用。

通過和小A的交流,我也看到了許多開發者的問題,雖然開發版本用的是 Java 8,但實際用的還是 Java 8 之前的最基礎的語法,對 Java 8 新增的特性一無所知。

Java 8 至 2014 年發布至今,已經過了 6 個年頭了,最新的 Java 14 都發布了,OK,這個不在本篇討論范圍之內, Java 8+ 系列教程請關注公眾號Java技術棧回復 "java" 進行閱讀,本篇就是想順著問小A的這個問題展開。

什么是默認方法和靜態方法?

上面也說了,Java 8 開始是可以有方法實現的,可以在接口中添加默認方法和靜態方法。

默認方法用 default 修飾,只能用在接口中,靜態方法用 static 修飾,這個我們不陌生了。并且接口中的默認方法、靜態方法可以同時有多個。

在接口中寫實現方法一點也不稀奇,像這樣的用法,從 Java 8 到 Java 14 已是遍地開花,到處都可以看到接口默認方法和靜態方法的身影。

比如我們來看下在 JDK API 中 java.util.Map 關于接口默認方法和靜態方法的應用。

  1. /* 
  2. * 來源公眾號:Java技術棧  
  3. */ 
  4. public interface Map<K,V> { 
  5.  
  6.     ... 
  7.      
  8.     /** 
  9.     * 接口默認方法 
  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.     * 接口靜態方法 
  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. }     

為什么要有接口默認方法?

舉一個很現實的例子:

我們的接口老早就寫好了,后面因為各種業務問題,避免不了要修改接口。

在 Java 8 之前,比如要在一個接口中添加一個抽象方法,那所有的接口實現類都要去實現這個方法,不然就會編譯錯誤,而某些實現類根本就不需要實現這個方法也被迫要寫一個空實現,改動會非常大。

所以,接口默認方法就是為了解決這個問題,只要在一個接口添加了一個默認方法,所有的實現類就自動繼承,不需要改動任何實現類,也不會影響業務,爽歪歪。

另外,接口默認方法可以被接口實現類重寫。

為什么要有接口靜態方法?

接口靜態方法和默認方法類似,只是接口靜態方法不可以被接口實現類重寫。

接口靜態方法只可以直接通過靜態方法所在的 接口名.靜態方法名 來調用。

接口默認方法多繼承沖突問題

因為接口默認方法可以被繼承并重寫,如果繼承的多個接口都存在相同的默認方法,那就存在沖突問題。

下面我會列舉 3 個沖突示例場景。

沖突一

來看下面這段程序:

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

Boy 同時繼承了 People 和 Man,此時在 IDEA 編輯器中就會報錯:

 

這就是接口多繼承帶來的沖突問題,Boy 不知道該繼承誰的,這顯然也是個問題,IDEA 也會提示,需要重寫這個方法才能解決問題:

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

在方法里面還能直接調用指定父接口的默認方法,比如:

  1. /* 
  2. * 來源公眾號:Java技術棧  
  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.  } 

再加個實現類測試一下:

  1. /* 
  2. * 來源公眾號:Java技術棧  
  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. 男孩吃飯 

嗯,很強大!

沖突二

我們再換一種寫法,把 Man 繼承 People,然后 Man 重寫 People 中的默認方法。

 

此時,編輯器不報錯了,而 People 的默認方法置灰了,提示沒有被用到。

再運行一下上面的示例,輸出:

男人吃飯

因為 Man 繼承 People,Man 又重定了默認方法。很顯然,這個時候,Boy 知道該繼承誰的默認方法了。

沖突三

在 Man 接口中新增一個方法:say,然后在 Boy 接口中新增一個默認方法:say。

 

這時候,Man 中的抽象方法居然被忽略了,IDEA 都提示說沒用到,這顯然是默認方法優先于抽象方法。

總結

本文介紹了 Java 8 的默認方法和靜態方法,以及默認方法的沖突問題解決方案。所以,大家出去面試時,再也不要說接口不能寫實現方法了,那就太 OUT 了。。

文中只舉了 3 個默認方法的沖突場景,不確定還沒有更多沖突問題。默認方法雖然解決了接口變動帶來的問題,但如果設計不當,或者過度設計,其帶來的方法沖突問題也是需要引起注意的。

本文轉載自微信公眾號「 Java技術棧」,可以通過以下二維碼關注。轉載本文請聯系 Java技術棧公眾號。

 

責任編輯:武曉燕 來源: Java技術棧
相關推薦

2022-07-15 14:58:26

數據分析人工智能IT

2014-11-21 10:25:26

2023-02-10 08:44:05

KafkaLinkedIn模式

2011-11-30 09:28:37

iCloud信息圖云計算

2021-08-09 14:40:02

物聯網IOT智能家居

2012-12-31 11:22:58

開源開放

2020-09-11 10:55:10

useState組件前端

2025-04-11 08:42:10

Java對象TLAB

2021-10-05 21:03:54

BeautifulSo 爬蟲

2022-04-24 09:00:00

滲透測試安全數字時代

2022-12-30 11:24:21

2014-08-25 11:22:30

2023-09-11 07:36:35

2018-06-15 23:00:56

2020-05-12 10:43:24

物聯網數據技術

2022-07-06 10:07:21

物聯網IoT

2022-09-01 15:26:45

物聯網人工智能傳感器

2023-05-28 18:21:32

2020-04-21 14:49:35

物聯網數據技術

2022-08-27 12:15:51

Linux Mint操作系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 蜜桃精品视频在线 | 久久精品天堂 | 欧美一区二区三区高清视频 | 欧美精品在欧美一区二区少妇 | 在线视频国产一区 | 国产精品毛片一区二区在线看 | 天天干狠狠 | 看片一区 | 中文字幕日韩一区 | 国产三级电影网站 | 精产嫩模国品一二三区 | 欧美激情国产日韩精品一区18 | 国产精品久久久久久妇女6080 | 国产精品美女久久久久久免费 | 不用播放器看的av | 色婷婷狠狠 | 精品在线播放 | 狠狠爱免费视频 | 日韩第1页 | 日韩在线小视频 | 日本午夜网站 | 国内自拍偷拍视频 | 亚洲精品久久久 | 国产精品乱码一区二区三区 | 欧美日韩不卡合集视频 | 在线亚洲人成电影网站色www | 日韩欧美在线免费观看 | 99久久精品国产一区二区三区 | 亚洲成人精品国产 | 亚洲一区播放 | 一区视频在线免费观看 | 国产精品久久久久久久久动漫 | 亚洲视频一区在线播放 | 国产在线精品一区二区 | 亚洲精品视频免费观看 | 黑人久久久 | 欧美成人手机在线 | 成人欧美日韩一区二区三区 | 免费一级欧美在线观看视频 | 成人午夜视频在线观看 | 97高清国语自产拍 |