4

次のコード スニペットには、 という名前のメソッドの 3 つのバージョンがありますshow()

package overloading;

import java.util.ArrayList;
import java.util.List;

public final class Main
{
    private void show(Object object)
    {
        System.out.println("Object");
    }

    private void show(List<Object> list)  //Unused method
    {
        System.out.println("List");
    }

    private void show(Object[] objects)
    {
        System.out.println("Objects");
    }

    private void addToList()
    {
        List<String>list=new ArrayList<String>();
        list.add("String1");
        list.add("String2");
        list.add("String3");
        show(list); // Invokes the first version

        String []s={"111", "222", "333"};
        show(s);   // Invokes the last version
    }

    public static void main(String[] args)
    {
        new Main().addToList();
    }
}

この最も単純な Java コードでは、このメソッド呼び出しshow(s);(メソッドの最後の行) がオーバーロードされたメソッドの最後のバージョンaddToList()を呼び出します。これは文字列の配列を提供し、type の受信パラメーターによって受け入れられます。String[]Object[]

ただし、この関数呼び出しは、オーバーロードされたメソッドの最初のバージョンshow(list);を呼び出そうとします。型文字列のリストを渡します。これは、受信パラメーターが型の中間バージョンによって受け入れられる必要があります。メソッドの中間バージョンは完全に使用されていません。最初のバージョンが削除されると、コンパイル時エラーになります。List<String>List<Object>

この呼び出しがこのバージョン (中間バージョン) を呼び出さshow(list); ないのはなぜですか?private void show(List<Object> list){}

4

3 に答える 3

7

要するに、でList<Object>はありませんList<String>

コードを「修正」するには、次のコードを使用します

private void show(List<? extends Object> list)
{
    System.out.println("List");
}

配列(Javaでは共変)とは異なり、ジェネリック型のさまざまなインスタンス化は、明示的にも、相互に互換性がありません。

宣言を使用Generic<Supertype> superGeneric; Generic<Subtype> subGeneric; すると、コンパイラはキャスト(Generic<Subtype>)superGenericとの両方の変換エラーを報告します(Generic<Supertype>)subGeneric

この非互換性は、実際の型パラメーターとして使用される場合、ワイルドカードによって緩和される可能性があります。これは、ジェネリック型のすべてのインスタンス化の抽象スーパータイプです。?Generic<?>

参照してください

于 2012-12-26T02:03:22.863 に答える
4

List<Object>List<String>in javaのスーパークラスではありません。あなたが想定しているのは、Java にはジェネリックスに関する共分散があるということですが、そうではありません。

これが意味することは、 が のスーパークラスである場合、Aは のスーパークラスでBList<A>ないということですList<B>

同様の問題は、ジェネリックを展開されたネストされた型に変換できません で直面しています。そこにある回避策のいずれかが機能するかどうかを確認できます。

変わってるかも

private void show(List<Object> list)

private void show(List<? extends Object> list)

期待どおりに動作しますか?

于 2012-12-26T01:52:39.333 に答える