日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 8的默认方法:可以做什么和不能做什么?

發布時間:2023/12/3 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 8的默认方法:可以做什么和不能做什么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是默認方法

在Java 8發行版中,您可以修改接口以添加新方法,以便該接口與實現該接口的類保持兼容。 如果您要開發一個庫,該庫將由基輔到紐約的幾位程序員使用,那么這非常重要。 在Java 8出現之前,如果您在庫中發布了接口,則您不能添加新方法,而不必冒險在接口中實現的某些應用程序會隨接口的新版本而中斷。

使用Java 8,這種恐懼消失了嗎? 沒有。

向接口添加默認方法可能會使某些類無法使用。

首先讓我們看一下默認方法的要點。

在Java 8中,可以在接口中實現一種方法。 (從Java8開始,靜態方法也可以在接口中實現,但這是另一回事。)在接口中實現的方法稱為默認方法,用關鍵字default表示為修飾符。 當類實現接口時,它可以但不必實現已經在接口中實現的方法。 該類繼承默認實現。 這就是為什么當接口實現更改時可能不需要觸摸類的原因。

多重繼承?

當一個具體的類實現多個(例如兩個)接口并且這些接口實現相同的默認方法時,事情就變得復雜起來。 該類將繼承哪個默認方法? 答案是否定的。 在這種情況下,該類必須自己實現該方法(直接實現或通過繼承更高級別的類)。

當只有一個接口實現默認方法而另一個僅將其聲明為抽象方法時,也是如此。 Java 8試圖受到約束,并避免“隱式”的事情。 如果在多個接口中聲明了這些方法,則不會繼承任何默認實現,則將出現編譯時錯誤。

但是,如果您已經編譯了類,則不會出現編譯時錯誤。 這樣Java 8不一致。 它有其原因,我不想在這里詳述或出于各種原因而進入辯論(例如:發布已結束,辯論時間很長,并且從未在此平臺上使用)。

  • 假設您有兩個接口,還有一個實現這兩個接口的類。
  • 接口之一實現默認方法m() 。
  • 您編譯所有接口和類。
  • 您更改不包含方法m()的接口,以將其聲明為抽象方法。
  • 僅編譯修改后的接口。
  • 運行課程。


在這種情況下,該類將運行。 您不能使用修改后的接口再次對其進行編譯,但是如果它是使用較舊版本進行編譯的:它仍然可以運行。 現在

  • 修改具有抽象方法m()的接口并創建默認實現。
  • 編譯修改后的接口。
  • 運行類:失敗。

當有兩個接口為同一方法提供默認實現時,該方法不能在實現類中調用,除非由該類實現(再次:直接或從另一個類繼承)。
該類是兼容的。 可以使用新界面加載它。 只要兩個接口中都沒有默認實現的方法的調用,它甚至可以開始執行。

樣例代碼

為了演示上述內容,我為類C.java創建了一個測試目錄,并為文件I1.java和I2.java的接口創建了三個子目錄。 測試的根目錄在文件C.java包含類C的源代碼。 目錄base包含適合執行和編譯的接口版本。 I1包含具有默認實現的方法m() 。 接口I2目前不包含任何方法。

該類包含一個main方法,因此我們可以在測試中執行它。 它測試是否存在任何命令行參數,因此我們可以輕松地執行該方法,而無需調用方法m() 。

~/github/test$ cat C.java public class C implements I1, I2 {public static void main(String[] args) {C c = new C();if( args.length == 0 ){c.m();}} } ~/github/test$ cat base/I1.java public interface I1 {default void m(){System.out.println("hello interface 1");} } ~/github/test$ cat base/I2.java public interface I2 { }

我們可以使用命令行來編譯和運行該類:

~/github/test$ javac -cp .:base C.java ~/github/test$ java -cp .:base C hello interface 1

compatible目錄包含聲明方法m()抽象的接口I2版本,并且出于技術原因,它包含未I1.java 。

~/github/test$ cat compatible/I2.java public interface I2 {void m(); }

這不能用于編譯類C :

~/github/test$ javac -cp .:compatible C.java C.java:1: error: C is not abstract and does not override abstract method m() in I2 public class C implements I1, I2 {^ 1 error

該錯誤信息非常準確。 即使我們具有先前編譯中的C.class ,并且即使在compatible目錄中編譯接口,我們仍將有兩個接口可用于運行該類:

~/github/test$ javac compatible/I*.java ~/github/test$ java -cp .:compatible C hello interface 1

wrong的第三個目錄包含I2版本,該版本還定義了方法m() :

~/github/test$ cat wrong/I2.java public interface I2 {default void m(){System.out.println("hello interface 2");} }

我們甚至不應該去編譯它。 即使方法是雙重定義的,只要不調用該方法,該類仍然可以執行,但是只要我們嘗試調用方法m() ,該類就會失敗。 這就是我們使用命令行參數的目的:

~/github/test$ javac wrong/*.java ~/github/test$ java -cp .:wrong C Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting default methods: I1.m I2.mat C.m(C.java)at C.main(C.java:5) ~/github/test$ java -cp .:wrong C x ~/github/test$

結論

當您開始將庫移至Java 8并修改接口以添加默認實現時,您可能不會遇到問題。 至少這是Java 8庫開發人員希望將功能方法添加到集合中的方式。 使用您的庫的應用程序仍然依賴沒有默認方法的Java 7庫。 使用和修改不同的庫時,沖突的可能性很小。 如何避免這種情況?

像以前一樣設計您的庫API。 不要輕易依賴默認方法的可能性。 他們是不得已的選擇。 明智地選擇名稱,以避免與其他接口沖突。 我們將學習如何使用此功能來開發Java編程。

翻譯自: https://www.javacodegeeks.com/2014/04/java-8-default-methods-what-can-and-can-not-do.html

總結

以上是生活随笔為你收集整理的Java 8的默认方法:可以做什么和不能做什么?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。