Java汎用型の簡明な解釈

2724 ワード

Java汎用由来の動機
Java汎用を理解する最も簡単な方法は、Javaタイプ変換(casting)の操作を節約する便利な文法と見なすことです.
List<Apple> apples=...
Apple apple=apples.get(1);

以上のようなコードは,プログラマが手動でタイプ判断を行う必要はないが,汎用型のため,コンパイラ段階でタイプをチェックした.
汎用的な構成
汎型の構成からタイプ変数の概念を引き出した.Java言語仕様では、タイプ変数は制限のないフラグであり、次のような状況で発生します.
  • 汎用クラス宣言
  • 汎用インタフェース宣言
  • 汎用メソッド宣言
  • 汎用コンストラクタ宣言
  • 汎用クラスとインタフェース
    public interface List<T> extends Collections<T>{
    
    }

    汎用メソッドとコンストラクタ
    public static <T> getFirstItem(List<T> list){
    }

    汎用タイプのサブタイプ
    このような3つの果物があるとします.
    FujiApple,
    Apple,
    Fruit
    FujiAppleはAppleのサブクラス、AppleはFruitのサブクラス、では
    List,
    List,
    List,
    三者の関係は何ですか.
    List<Apple> apples=new ArrayList<Apple>();
    List<Fruit> fruits=apples;

    上のコードは正しいですか?答えはコンパイルエラーです.
    どうしてですか.次のコードを見てください
    List<Apple> apples=new ArrayList<Apple>();
    List<Fruit> fruits=apples;
    fruits.add(new Strawberry());//Strawberry   ,       

    AppleがFruitのサブタイプであれば、ListがListのサブタイプであると考えると、Listは自然にaddイチゴをaddすることができる.
    しかし、これは汎用型がタイプを決定するための公理に反している.これでリストにはいろいろなタイプが使われているので、出すときは手動で
    タイプを判断しました.
    したがって、ListはListとは関係ありません.
    ワイルドカード
    汎用オブジェクトの参照を上に作成
    List<Apple> apples=...
    List<? extends Fruit> fruits=apples

    上記のコードでは、2つの汎用オブジェクトに継承関係を持たせる場合は、ワイルドカードを使用します.
    「?extends」は汎用タイプのサブタイプ相関が現実になった:AppleはFruitのサブタイプ、ListはListのサブタイプ.
    しかし、fruitsにデータを入れることはできません.もちろんFruitを取り出すことはできます.
    汎用オブジェクトの参照を下に作成
    List<Fruit> fruits=...
    List<? super Apple> apples=fruits;

    fruitsがAppleを搭載したスーパークラス(supertype)のリストを指しているのを見た.同様に、スーパークラスとは何か分かりませんが、AppleとどのAppleのサブクラスもそのタイプと互換性があることを知っています.この未知のタイプがAppleであり、GreenAppleのスーパークラスである以上、私たちは書くことができます.
    apples.add(new GreenApple);
    apples.add(new Apple());
    applesにapplesのスーパークラスを追加しようとすると、コンパイラは警告します.
    apples.add(new Fruit());
    apples.add(new Object());
    ただし、オブジェクトを取り出す必要がある場合、取り出すのはObjectオブジェクトのみです.
    アクセスの原則とPECSの法則
    まとめ?extendsとthe?superワイルドカードの特徴は、以下の結論を得ることができます.
  • データ型からデータを取得したい場合は、使用しますか?extendsワイルドカード
  • オブジェクトをデータ構造に書き込む場合は、使用しますか?superワイルドカード
  • 貯金したいし、取りたいならワイルドカードを使わないでください.

  • このPECSとは「Producer Extends,Consumer Super」のことです
    参考書:
  • The Java Tutorial
  • Java Generics and Collections, by Maurice Naftalin and Philip Wadler
  • Effective Java中国語版(第2版)、by Joshua Bloch.