ホームページ Java &#&チュートリアル Java8のデフォルトメソッドの詳細な紹介

Java8のデフォルトメソッドの詳細な紹介

Jan 23, 2017 pm 03:15 PM

デフォルトの方法は何ですか?

Java 8 のリリース後、新しいメソッドをインターフェースに追加できますが、インターフェースはその実装クラスとの互換性を維持できます。開発するライブラリは複数の開発者によって広く使用される可能性があるため、これは重要です。 Java 8 より前では、クラス ライブラリでインターフェイスが公開された後、新しいメソッドがインターフェイスに追加された場合、このインターフェイスを実装したアプリケーションは、新しいバージョンのインターフェイスを使用するとクラッシュする危険がありました。

Java 8 ではそのような危険はありませんか?答えは否定的です。

デフォルトのメソッドをインターフェースに追加すると、特定の実装クラスが使用できなくなる可能性があります。

まず、デフォルトのメソッドの詳細を見てみましょう。

Java 8 では、インターフェイス内のメソッドを実装できます (Java 8 の静的メソッドもインターフェイス内に実装できますが、これは別のトピックです)。インターフェイスに実装されたメソッドはデフォルト メソッドと呼ばれ、修飾子としてキーワード default で識別されます。クラスがインターフェイスを実装する場合、そのインターフェイスにすでに実装されているメソッドを実装できますが、これは必須ではありません。このクラスはデフォルトのメソッドを継承します。これが、インターフェースが変更された場合に実装クラスを変更する必要がない理由です。

多重継承がある場合はどうなるでしょうか?

クラスが複数(2 つなど)のインターフェイスを実装し、これらのインターフェイスが同じデフォルト メソッドを持つ場合、事態は非常に複雑になります。クラスはどのデフォルト メソッドを継承しますか?どちらでもない!この場合、クラス自体 (直接、または継承ツリーの上位クラス) がデフォルト メソッドを実装する必要があります。

あるインターフェースがデフォルトメソッドを実装し、別のインターフェースがデフォルトメソッドを抽象として宣言する場合も同様です。 Java 8 は曖昧さを避け、厳密さを維持しようとします。メソッドが複数のインターフェイスで宣言されている場合、デフォルトの実装は継承されず、コンパイル時エラーが発生します。

ただし、クラスをコンパイルした場合、コンパイル時エラーは発生しません。この時点で、Java 8 には一貫性がありません。これには独自の理由があり、ここでは詳細に説明したり、深く議論したくありません (理由: バージョンがリリースされており、議論の時間が長すぎるため、このプラットフォームにはこれまでにないものがあります)。そのような議論)。

1. 2 つのインターフェイスと 1 つの実装クラスがあるとします。
2. インターフェースの 1 つはデフォルトのメソッド m() を実装します。
3. インターフェースと実装クラスを一緒にコンパイルします。
4. m() メソッドを含まないインターフェイスを変更し、m() メソッドを抽象として宣言します。
5. 変更したインターフェースを個別に再コンパイルします。
6. 実装クラスを実行します。

Java8のデフォルトメソッドの詳細な紹介

上記の場合、クラスは正常に実行できます。ただし、変更されたインターフェイスで再コンパイルすることはできませんが、古いインターフェイスでのコンパイルは引き続き実行できます。次に


1. 抽象メソッド m() を含むインターフェースを変更し、デフォルトの実装を作成します。
2. 変更したインターフェースをコンパイルします。
3. クラスを実行します: 失敗しました。
2 つのインターフェイスが同じメソッドのデフォルト実装を提供する場合、実装クラスもデフォルト メソッドを実装しない限り (直接、または継承ツリーの上位レベルのクラスによって)、このメソッドを呼び出すことはできません。

Java8のデフォルトメソッドの詳細な紹介

ただし、このクラスは互換性があります。新しいインターフェースを使用してロードでき、両方のインターフェースにデフォルト実装があるメソッドを呼び出さない限り、実行することもできます。


サンプルコード:

Java8のデフォルトメソッドの詳細な紹介

上記の例を示すために、C.java のテスト ディレクトリを作成し、その下に I1.java と I2.java を保存する 3 つのサブディレクトリがあります。テスト ディレクトリには、クラス C のソース コード C.java が含まれています。ベース ディレクトリには、コンパイルして実行できるインターフェイスのバージョンが含まれています。 I1 にはデフォルト実装の m() メソッドが含まれていますが、I2 にはメソッドが含まれていません。

実装クラスにはmainメソッドが含まれているので、テストで実行できます。コマンドラインパラメータがあるかどうかをチェックするので、m() を呼び出すテストと 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
ログイン後にコピー

互換ディレクトリには、抽象メソッド m() を含む I2 インターフェイスと、未変更の I1 インターフェイスが含まれています。

~/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 があるため、互換性のあるディレクトリでインターフェイスをコンパイルすると、実装クラスを実行できる 2 つのインターフェイスが引き続き得られます:

~/github/test$ javac compatible/I*.java
~/github/test$ java -cp .:compatible C
hello interface 1
ログイン後にコピー

間違って呼ばれる 3 番目のディレクトリには、I2 インターフェイスも含まれていますm() メソッドは次のように定義されています:

~/github/test$ cat wrong/I2.java
public interface I2 {
  default void m(){
    System.out.println("hello interface 2");
  }
}
ログイン後にコピー

我们应该不厌其烦的编译它。尽管m()方法被定义了两次,但是,实现类仍然可以运行,只要它没有调用那个定义了多次的方法,但是,只要我们调用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.m
    at C.m(C.java)
    at C.main(C.java:5)
~/github/test$ java -cp .:wrong C x
~/github/test$
ログイン後にコピー

结论

当你把给接口添加了default实现的类库移植到Java 8环境下的时候,一般不会有问题。至少Java8类库开发者给集合类添加default方法的时候就是这么想的。使用你类库的应用程序仍然依赖没有default方法的Java7的类库。当使用和修改多个不同的类库的时候,有很小的几率会发生冲突。如何才能避免呢?

像以前那样设计你的类库。可能依赖default方法的时候不要掉以轻心。万不得已不要使用。明智的选择方法名,避免和其它接口产生冲突。我们将会学习到Java编程中如何使用这个特性做开发。

更多Java8のデフォルトメソッドの詳細な紹介相关文章请关注PHP中文网!

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか? カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか? Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

Javaで機能的なプログラミング技術を実装するにはどうすればよいですか? Javaで機能的なプログラミング技術を実装するにはどうすればよいですか? Mar 11, 2025 pm 05:51 PM

この記事では、Lambda式、Streams API、メソッド参照、およびオプションを使用して、機能プログラミングをJavaに統合することを調べます。 それは、簡潔さと不変性を通じてコードの読みやすさと保守性の改善などの利点を強調しています

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか? Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか? Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか? キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか? Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか? 高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか? Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

非ブロッキングI/OにJavaのNIO(新しい入出力)APIを使用するにはどうすればよいですか? 非ブロッキングI/OにJavaのNIO(新しい入出力)APIを使用するにはどうすればよいですか? Mar 11, 2025 pm 05:51 PM

この記事では、単一のスレッドで複数の接続を効率的に処理するためにセレクターとチャネルを使用して、非ブロッキングI/O用のJavaのNIO APIについて説明します。 プロセス、利点(スケーラビリティ、パフォーマンス)、および潜在的な落とし穴(複雑さ、

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか? 適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか? Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか? ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか? Mar 11, 2025 pm 05:53 PM

この記事では、ネットワーク通信のためのJavaのソケットAPI、クライアントサーバーのセットアップ、データ処理、リソース管理、エラー処理、セキュリティなどの重要な考慮事項をカバーしています。 また、パフォーマンスの最適化手法も調査します

See all articles