ホームページ  >  記事  >  Java  >  JavaジェネリックスのプレースホルダTと?の違いは何ですか?

JavaジェネリックスのプレースホルダTと?の違いは何ですか?

王林
王林転載
2023-05-11 18:10:061342ブラウズ

最初の 2 つのコード:

public static <T> void show1(List<T> list){
 for (Object object : list) {
        System.out.println(object.toString());
    }
}

public static void show2(List<?> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

show1 メソッドで T を使用していることがわかります。これがジェネリックスを記述する一般的な方法であることは誰もが知っているため、ここでの T は特定のタイプの特定のメソッドを指します。オブジェクトとリスト コレクションには同じ種類のデータのみを保存できます。異なる種類のデータを挿入すると、エラーが報告されます。

それでは、show2 メソッドでは何を使用するのでしょうか? void の前に <t></t> がないことがわかりますか?これはプレースホルダーとして表現できますが、リスト コレクションにいくつのデータ タイプが格納されるかはわかりません。したがって、これは、N 個のデータ タイプをリストに格納することも可能であることを示しています。

テスト コードを通して 2 つの違いを直観的に感じてみましょう:

public static void test(){
   List<Student> list1 = new ArrayList<>();
   list1.add(new Student("zhangsan",18,0));
   list1.add(new Student("lisi",28,0));
   list1.add(new Student("wangwu",24,1));
   //这里如果add(new Teacher(...));就会报错,因为我们已经给List指定了数据类型为Student
   show1(list1);

   System.out.println("************分割线**************");

   //这里我们并没有给List指定具体的数据类型,可以存放多种类型数据
   List list2 = new ArrayList<>();
   list2.add(new Student("zhaoliu",22,1));
   list2.add(new Teacher("sunba",30,0));
   show2(list2);
}

実行結果を見てみましょう:

Student{name= 'zhangsan '、年齢= 18、性別=0}
学生{名前='リシ'、年齢= 28、性別=0}
学生{名前='王武'、年齢= 24、性別=1}
************区切り線******************
学生{名前='zhaoliu'、年齢=22、 sex=1}
Teacher{name='sunba', age=30, sex=0}

show1 との違いは show2 メソッドから確認できます。List2 には 2 種類の Student が格納されていますデータを出力すると、これが T と ?~ 友達、わかりますか?

見てみましょう?拡張記述方法:

List extends data type> list

public static void show3(List<? extends Teacher> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

List extends Teacher> list この記述方法は、 Teacher とそのサブクラスのデータ型のリスト コレクションを受け取り、テスト メソッド show3(list2);Try:

Student{name=&#39;zhaoliu&#39;, age=22, sex=1}
Teacher{name=&#39;sunba&#39;, age=30, sex=0}

を作成できます。コレクション内のデータは正常に出力されるため、通常の出力が表示されます。これはすべて Teacher のサブクラス タイプです。List extends Teacher> listList extends Student> list? に変更するとどうなりますか?

JavaジェネリックスのプレースホルダTと?の違いは何ですか?

この図をよく見てください。新しい list3 を作成し、データ型を Teacher として宣言しました。この時点で、show3(List extends Student> list) エラーはすぐに報告されます。エラー メッセージは、Student は Teacher のサブクラスであり、Student とそのサブクラスのみを受け入れるため、Teacher を Student に変換できないことを示します。したがって、当然エラーが発生します。報告される。

List super data type> list

この書き方は、指定されたデータ型とその親クラス型のみを受け取ることを意味し、また、コードの一部を記述する簡単な方法 効果を見てください:

public static void show4(List<? super Student> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

受け取ったのは Student とその親クラスのコレクションであることがわかります。2 つのコレクション データを書き込み、それを呼び出します。試す。

List list4 = new ArrayList<>();
list4.add(new Student("sunba",30,0));
list4.add(new Teacher("zhaoliu",22,1));
show4(list4);

Student オブジェクトと Teacher オブジェクトをリストに挿入し、結果を確認します。

Student{name=&#39;sunba&#39;, age=30, sex=0}
Teacher{name=&#39;zhaoliu&#39;, age=22, sex=1}

何も問題はなく、正常に実行され、出力されます。

Student サブクラスのコレクションを渡した場合に何が起こるかを見てみましょう

JavaジェネリックスのプレースホルダTと?の違いは何ですか?

前と同じことがわかります。エラーは次のとおりです。 Student とその親クラスのみを受け取ることができるデータ型を定義したと考えて、同じ理由で報告されました。

最後に状況を見てみましょう

List を定義するときにデータ型を指定せず、Child、Student、Teacher を挿入するか、show4(List super Student> list)、エラーが報告されますか?エラーが報告されなかった場合、結果はどうなりますか?

JavaジェネリックスのプレースホルダTと?の違いは何ですか?

list は複数のデータ型を格納できるため、エラーは報告されないことがわかります。それでは、show4 メソッドを呼び出すと結果はどうなるでしょうか?

JavaジェネリックスのプレースホルダTと?の違いは何ですか?

プログラムが正常に実行され、結果が出力されることがわかります。Child は Student から継承しているため、受け取るのは Student とその親クラスのオブジェクト データ型であることに注意してください。したがって、プログラムは出力のために Child を親クラス Student に自動的に変換するため、誰もがこれに注意する必要があり、自動的に上向きに変換されます。

以上がJavaジェネリックスのプレースホルダTと?の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。