ホームページ  >  記事  >  Java  >  Java汎用コンテナコレクションの使い方

Java汎用コンテナコレクションの使い方

WBOY
WBOY転載
2023-04-19 18:10:42758ブラウズ

簡単な例から始めましょう:

<code>public void testGenerics() {<br>    Collection<Number> numbers = new ArrayList<>();<br>    numbers.add(1); // ok<br>    numbers.add(0.1); // ok<br><br>    Collection<? extends Number> numbers2 = new ArrayList<>();<br>    // don't work, you don't know which subtype 'numbers2' exactly contains<br>    numbers2.add(1); // oops!<br>}<br></code>

この例は、実際には少し反人間的なものです。この変換に対するほとんどの人 (私を含む) の最初の反応は、「もちろんです」であるはずです。そうです」 (これは私が罠に陥ったということです) について、私の理解を述べさせていただきます:

  • Collection: このコレクションには、すべての Number 型オブジェクトが含まれていることを示します。整数/長整数/浮動小数点、コンパイラは obj instanceof Number == true と判断できるため、

  • Collection: この Collection が「サブタイプ」の Collection インスタンスであることを示します" Number 型の Collection< Integer>/Collection である可能性があるため、numbers2.add(1) を呼び出しても機能しません。コンパイラは、numbers2 に含まれる要素が Number のどのサブタイプであるかを認識せず、コンパイラは、obj instanceof UnknownType;

  • Collection の結果を判断できません。この E 型は「ある」特定の型であり、親の複数のサブタイプを表すプレースホルダーにすることはできません。

別の例:

<code>public void testGenerics() {<br>    Collection<Number> numbers = new ArrayList<>();<br>    Collection<Integer> integers = new ArrayList<>();<br>    Collection<? extends Number> numbers2 = new ArrayList<>();<br>    <br>    numbers2 = integers; // ok<br>    numbers2 = numbers; // ok<br>    <br>    // don't work, Collection<Number> != Collection<Integer><br>    numbers = integers; // oops!<br>}<br></code>

Integer は明らかに Number を継承しますが、なぜ

  • Collection == Collection となるのでしょうか。

は確立されていません。例を見てみましょう:

<code>public void testGenerics() {<br>    Collection<Integer> profits = new ArrayList<>();<br>    <br>    insertSomething(profits); // line 1<br>    <br>    Integer profit = profits.iterator().next(); // oops! crash<br>}<br><br>private void insertSomething(Collection<Number> numbers) {<br>    numbers.add(Long.MAX_VALUE);<br>}<br></code>

1 行目が確立されている場合、次の利益は負の数になり、その後の一連の利益は負の数になります。コードが十分に堅牢でない場合、予期しない RuntimeException がスローされ、メソッドが異常終了したり、プログラムがクラッシュしたりする可能性もあります。

つまり、一言で言えば、 Collection != Collection は実行時の安全性を確保するためのものであり、発生する可能性のある型変換例外はコンパイル時に解決されます。

さて、Collection と Collection について話しましょう。私を含む多くの人が最初に抱く反応は、「Object はすべての Java オブジェクトの共通の親クラスなので、Collection< 「Object> は任意のタイプのコレクションを表すことができます」例を見てみましょう:

<code>public void testGenerics2() {<br>    Collection<Integer> integers = new ArrayList<>();<br><br>    Collection<?> objects2 = integers; // ok<br>    // don't work, which type of 'objects2' contains is uncertain<br>    objects2.add(1); // oops!<br>    <br>    Collection<Object> objects = integers; // oops!<br>}<br></code>
  • Collection は Collection;

    よりも広い範囲を表します

  • Objects2.add(1) は、コンパイラーがコンテナー object2 のデータ型を正確に推論できないため呼び出すことができません。実行時型変換例外が発生する可能性があります。

  • 任意のデータ型のコレクションを記述する正しい方法は、Collection;

  • ##Collection は、任意の型のコレクションを表すことはできません。

  • ##Collection がどの型のコレクションも表さないのはなぜですか? 実際、コンパイラは型変換エラーのリスクがあると考えています:
    <code>public void testGenerics() {<br>    Collection<Integer> integers = new ArrayList<>();<br><br>    Collection<Object> objects = integers; // oops!<br>    // don't work, which type of 'objects2' contains is uncertain<br>    objects.add("1");<br><br>    Integer one = objects.iterator().next(); // oops! crash<br>}<br></code>

    Collection は、Object がすべてのオブジェクトの親クラスであり、既知の型であるため、コンテナにデータを追加できます。これは、obj instanceof Object によって判断できます;