2つのインターフェイスの戻り値の型が競合している場合、なぜ1つのメソッドがデフォルトになるのですか?

schmod:

Java 8では、戻り値の型が異なる(ただし互換性のある)2つのインターフェースがある場合、リフレクションにより、2つのメソッドの1つがデフォルトのメソッドであることが示されます。

たとえば、次のコードスニペットを取ります。

package com.company;
import java.lang.reflect.Method;

interface BarInterface {}
class Bar implements BarInterface {}

interface FooInterface {
    public BarInterface getBar();
}

interface FooInterface2 extends FooInterface {
    public Bar getBar();
}

class Foo implements FooInterface2 {
    public Bar getBar(){
        throw new UnsupportedOperationException();
    }
}

public class Main {
    public static void main(String[] args) {
        for(Method m : FooInterface2.class.getMethods()){
            System.out.println(m);
        }
    }
}

Java 1.8は次の出力を生成します。

public abstract com.company.Bar com.company.FooInterface2.getBar()
public default com.company.BarInterface com.company.FooInterface2.getBar()

これは奇妙に思えます。両方のメソッドが存在するためだけでなく、メソッドの1つが突然、そして不可解にデフォルトのメソッドになったためです

Java 7で同じコードを実行すると、両方のメソッドのシグネチャが同じであることを考えると、混乱するかもしれませんが、少し予期しない結果が生じます。

public abstract com.company.Bar com.company.FooInterface2.getBar()
public abstract com.company.BarInterface com.company.FooInterface.getBar()

Javaは複数の戻り値の型をサポートしていないので、この結果はまだ奇妙です。


次の考えは明白です:「わかりました。これは、これらのメソッドに実装がないため、インターフェイスにのみ適用される特別な動作である可能性があります。」

違う。

class Foo2 implements FooInterface2 {
    public Bar getBar(){
        throw new UnsupportedOperationException();
    }
}

public class Main {
    public static void main(String[] args) {
        for(Method m : Foo2.class.getMethods()){
            System.out.println(m);
        }
    }
}

収量

public com.company.Bar com.company.Foo2.getBar()
public com.company.BarInterface com.company.Foo2.getBar()

何が起きてる?Javaがこれらを個別のメソッドとして列挙するのはなぜですか。また、インターフェースメソッドの1つが実装されていないデフォルトのメソッドになるように管理されているのはなぜですか。

ピーター・ローリー:

これは、defaultユーザーが提供する方法ではなく、ブリッジ方法です。定義した親インターフェース。

public BarInterface getBar();

そして、これを実装する呼び出し可能なメソッドが必要です。

例えば

FooInterface fi = new Foo();
BarInterface bi = fi.getBar(); // calls BarInterface getBar()

ただし、それは共変の戻り値型を呼び出すことができる必要もあります。

FooInterface2 fi = new Foo();
Bar bar = fi.getBar(); // calls Bar getBar()

これらは同じメソッドですが、唯一の違いは、一方が他方を呼び出し、戻り値をキャストすることです。これを行うのはdefaultインターフェース上にあるため実装があるように見えるメソッドです。

注:複数レベルのインターフェース/クラスがあり、それぞれに異なる戻り値のタイプがある場合、メソッドの数は累積します。

これを行う理由は、戻り値の型がシグネチャの一部であるためJVM は戻り値の型が異なる複数のメソッドを持つことができるためです。私は呼び出し側が期待している戻り値の型を指定する必要があり、JVMは実際には共変戻り値の型を理解していません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

2つのインターフェースに同じデフォルトメソッドが含まれている場合はどうなりますか?

分類Dev

Java 8-2つのインターフェースには、メソッドシグネチャは同じであるが戻り値のタイプが異なるデフォルトメソッドが含まれています。どのようにオーバーライドするのですか?

分類Dev

2つのインターフェースを実装し、デフォルトのメソッドの競合を解決するJava:なぜsuperキーワードを使用するのですか?

分類Dev

型の値を、その型へのレシーバー型ポインターを持つメソッドを実装するインターフェースに割り当てることができないのはなぜですか?

分類Dev

メソッドシグネチャが同じで戻り値の型が異なる2つのインターフェイスを実装する

分類Dev

nullオブジェクトポインタのデータにアクセスしないメソッドを呼び出すと、機能する場合とクラッシュする場合があります。なぜいつもクラッシュしないのですか?

分類Dev

戻り値の型が 'T'であり、メソッドパラメータがワイルドカードで構成されている場合の戻り値の型とメソッドパラメータの競合

分類Dev

golangでは、メソッドの1つにポインターレシーバーが必要な場合、ポインターレシーバーを持つように型のすべてのメソッドを変更する必要がありますか?

分類Dev

インターフェイスにデフォルトのメソッド実装が付属しているのに、WELDがUnsupportedOperationExceptionをスローするのはなぜですか?

分類Dev

デバッグが実行されてもリリースがビルドされないのはなぜですか。同じソースファイルを使用しているプロジェクトの1つに対してのみです。

分類Dev

デフォルトのメソッドとしてインターフェイスにtoString()を追加できないのはなぜですか?

分類Dev

戻り値の型を持つJavaメソッド参照がコンシューマインターフェイスと一致するのはなぜですか?

分類Dev

Stringerインターフェイスメソッドが呼び出されないのはなぜですか?fmt.Printlnを使用する場合

分類Dev

値の1つとしてハイフンを使用しながら、文字列データ型のキーのリスト内の値を合計する方法

分類Dev

サブクラスのインスタンスメソッドが同じシグネチャと異なる戻り値の型を持っている場合、それはオーバーライドメソッドですか、それとも新しいメソッドですか?

分類Dev

ラムダを返すこのメソッドがインターフェイスメソッドの戻り値の型に依存するのはなぜですか?

分類Dev

C#でデフォルトのインターフェイスメソッドを使用する必要があるのはいつですか?

分類Dev

Java-戻りの型が独自のメソッドパラメータ型にジェネリックを使用する場合の拡張インターフェースの戻りの型のオーバーライド

分類Dev

インターフェース、すべての実装がすべてのメソッドを使用しているわけではない場合

分類Dev

取得できるオブジェクトが1つしかない場合の、DjangoORMでのフィルターとパフォーマンスの取得

分類Dev

「データソース名が見つからず、デフォルトのドライバーが指定されていない」というメッセージが表示されるのはなぜですか。どうすれば修正できますか?

分類Dev

型以外のテンプレートパラメータを持つクラスが与えられた場合、引数の値の任意のペアについて、クラスが相互にフレンドになる可能性はありますか?

分類Dev

2つのクラスのヘッダーファイルをどのように配置し、それらが互いにインクルードする必要がある場合、不完全なタイプを回避する必要がありますか?

分類Dev

#1と#2のパラメータを使用したBashスクリプトですが、ファイルが見つからない場合は、ユーザーからの読み取りに戻ります

分類Dev

メソッドで必要なオブジェクトフィールドが1つだけの場合、パラメーターとして何を渡す必要がありますか-オブジェクトまたはフィールド値?

分類Dev

メソッドの戻り型が指定されていないインターフェースを作ることは可能ですか?

分類Dev

ライブラリ/ドキュメントのショートカットに、すべてのサブフォルダーのすべてのファイルが1つのフラットリストに表示されるのはなぜですか?

分類Dev

1つのフィールドにデフォルト値がない場合、Laravelに行を挿入するにはどうすればよいですか?

分類Dev

:: 1がインターフェイス1にあるのに、なぜこのソケットを:: 1%2にバインドできるのですか?

Related 関連記事

  1. 1

    2つのインターフェースに同じデフォルトメソッドが含まれている場合はどうなりますか?

  2. 2

    Java 8-2つのインターフェースには、メソッドシグネチャは同じであるが戻り値のタイプが異なるデフォルトメソッドが含まれています。どのようにオーバーライドするのですか?

  3. 3

    2つのインターフェースを実装し、デフォルトのメソッドの競合を解決するJava:なぜsuperキーワードを使用するのですか?

  4. 4

    型の値を、その型へのレシーバー型ポインターを持つメソッドを実装するインターフェースに割り当てることができないのはなぜですか?

  5. 5

    メソッドシグネチャが同じで戻り値の型が異なる2つのインターフェイスを実装する

  6. 6

    nullオブジェクトポインタのデータにアクセスしないメソッドを呼び出すと、機能する場合とクラッシュする場合があります。なぜいつもクラッシュしないのですか?

  7. 7

    戻り値の型が 'T'であり、メソッドパラメータがワイルドカードで構成されている場合の戻り値の型とメソッドパラメータの競合

  8. 8

    golangでは、メソッドの1つにポインターレシーバーが必要な場合、ポインターレシーバーを持つように型のすべてのメソッドを変更する必要がありますか?

  9. 9

    インターフェイスにデフォルトのメソッド実装が付属しているのに、WELDがUnsupportedOperationExceptionをスローするのはなぜですか?

  10. 10

    デバッグが実行されてもリリースがビルドされないのはなぜですか。同じソースファイルを使用しているプロジェクトの1つに対してのみです。

  11. 11

    デフォルトのメソッドとしてインターフェイスにtoString()を追加できないのはなぜですか?

  12. 12

    戻り値の型を持つJavaメソッド参照がコンシューマインターフェイスと一致するのはなぜですか?

  13. 13

    Stringerインターフェイスメソッドが呼び出されないのはなぜですか?fmt.Printlnを使用する場合

  14. 14

    値の1つとしてハイフンを使用しながら、文字列データ型のキーのリスト内の値を合計する方法

  15. 15

    サブクラスのインスタンスメソッドが同じシグネチャと異なる戻り値の型を持っている場合、それはオーバーライドメソッドですか、それとも新しいメソッドですか?

  16. 16

    ラムダを返すこのメソッドがインターフェイスメソッドの戻り値の型に依存するのはなぜですか?

  17. 17

    C#でデフォルトのインターフェイスメソッドを使用する必要があるのはいつですか?

  18. 18

    Java-戻りの型が独自のメソッドパラメータ型にジェネリックを使用する場合の拡張インターフェースの戻りの型のオーバーライド

  19. 19

    インターフェース、すべての実装がすべてのメソッドを使用しているわけではない場合

  20. 20

    取得できるオブジェクトが1つしかない場合の、DjangoORMでのフィルターとパフォーマンスの取得

  21. 21

    「データソース名が見つからず、デフォルトのドライバーが指定されていない」というメッセージが表示されるのはなぜですか。どうすれば修正できますか?

  22. 22

    型以外のテンプレートパラメータを持つクラスが与えられた場合、引数の値の任意のペアについて、クラスが相互にフレンドになる可能性はありますか?

  23. 23

    2つのクラスのヘッダーファイルをどのように配置し、それらが互いにインクルードする必要がある場合、不完全なタイプを回避する必要がありますか?

  24. 24

    #1と#2のパラメータを使用したBashスクリプトですが、ファイルが見つからない場合は、ユーザーからの読み取りに戻ります

  25. 25

    メソッドで必要なオブジェクトフィールドが1つだけの場合、パラメーターとして何を渡す必要がありますか-オブジェクトまたはフィールド値?

  26. 26

    メソッドの戻り型が指定されていないインターフェースを作ることは可能ですか?

  27. 27

    ライブラリ/ドキュメントのショートカットに、すべてのサブフォルダーのすべてのファイルが1つのフラットリストに表示されるのはなぜですか?

  28. 28

    1つのフィールドにデフォルト値がない場合、Laravelに行を挿入するにはどうすればよいですか?

  29. 29

    :: 1がインターフェイス1にあるのに、なぜこのソケットを:: 1%2にバインドできるのですか?

ホットタグ

アーカイブ