JAva基本功強固-jeneric


Generic


JDK1.JENERICは、5から新たに追加された機能として、様々なタイプのオブジェクトを扱う方法や集合クラスをコンパイルする際のタイプチェック(compile-timetypecheck)を行うことができる.
ジュネーブをサポートする前に、コレクションからオブジェクトを取り出すたびに変形します.そのため、誰かがうっかりインコヒーレントなタイプのオブジェクトを入れてしまうと、実行時に変換型エラーが発生します.逆にJENICを使用すると、コレクションに含まれるタイプをコンパイラに伝えることができ、思わぬオブジェクトをブロックし、より安全で明確なプログラムを生成することができます.
また、JENERICを知らないと、Java APIドキュメントを正常に表示できません.だからジェニーンリックはきっと!ぜひ知っておきたい.
ジェニーンリックを使わないと...
入力されたデータ型が分からない場合は、オブジェクト型でデータを受信し、変換するたびに処理する必要があり、パフォーマンスが低下します.

特長

  • コンパイル時に強いタイプチェックを行うことができます.(提供タイプセキュリティ)
  • タイプチェックとタイプ変換(鋳造)を削除します.(コードが簡略化された)
  • ≪タイプの安定性|Typeあんていせい|oem_src≫:予期しないタイプのオブジェクトの格納を防止し、格納されたオブジェクトを元のタイプとは異なるタイプに変換することを防止します.

    ジュネーブの使い方

    class Box<T> {}
    上のコードはJENICを使用するクラスの例です.各項目の表示:
  • Box:ジェニーリック教室」TのBoxまたは「T Box」と読みます.
  • T:タイプ変数またはタイプパラメータ.(Tはタイプ文字)
  • Box:オリジナルタイプ(オリジナルタイプ)
  • ジェニーンリックのタイプを指定するには、次のように宣言します.
    Box<String> b = new Box<String>();
  • Box『String』:JENNERICタイプコール
  • String:パラメトリックタイプ
  • ジェニーリック使用前

    class Box {
        Object item;
        
        void setItem(Object item) { this.item = item; }
        Object getItem() { return item; }
    }

    ジェニーンリックを使った後

    class Box<T> {  // 제네릭 타입 T를 선언
        T item;
        
        void setItem(T item) { this.item = item; }
        T getItem() { return item; }
    }
    タイプ変数は、Tではなく他のものを使用できます(ユーザはランダムに設定します).これらのタイプは記号のタイプが異なるだけで、「任意の参照タイプ」を表すのは同じです.
    したがって、後でBoxクラスのオブジェクトを作成するときに、参照変数(T)ではなくジェネレータで実際に使用するタイプを指定できます.
    Box<String> b = new Box<String>();  // 타입 T 대신, 실제 타입을 지정
    b.setItem(new Object());            // 에러. String 이외의 타입은 지정불가
    b.setITem("ABC");                   // 성공. String 타입이므로 가능
    String item = b.getItem();          // 형변환 필요 없음
    上記の例に示すように、参照変数ではなくStringタイプを指定すると、Boxクラスは次のように宣言されます.
    class Box {
        String item;
        
        void setItem(String item) { this.item = item; }
        String getItem() { return item; }
    }

    制限


    ジェニーリックのタイプ制限
    JENNERICタイプ呼び出しのタイプを一度に特定のインスタンスで代入する以外は、他のタイプを使用することはできません.
    Box<String> box = new Box<Integer>(); // 에러
    しかし、子供と親階級の間の継承関係の多形性は適用できる.

    ジュネーブこうへん

    ArrayList<Object> objectList = new ArrayList<String>();  // 컴파일 에러
    StringタイプがObjectタイプを拡張しても、JENICは可変であるため、コンパイルエラーが発生します.ただし、JENICタイプを使用して配列を作成してもコンパイルエラーは発生しません.これは配列が共変特性を有するためである.
    意味javaでは,キーワード共変性(コヒーレント)C[T']を用いてC[T]のサブクラス,extends半変性(逆変異)C[T]をC[T']のサブクラス,スーパー非共変性(不変量)C[T]とC[T']は何の関係もない.
    次の例で確認できます.
    class Course<T> {
        private String name;
        private T[] students;
        
        public Course(String name, int capacity) {
            this.name = name;
            // 배열은 공변이기 때문에 제네릭 타입으로 형변환한 배열을 생성할 수는 있다.
            // 하지만 이후 배열의 원소 사용이 불가능하다.
            students = (T[]) (new Object[capacity]);
        }
    
        // 배열 초기화 시 클래스 타입을 추가해줘야 한다.
        public Course(String name, int capacity, Class<T> tClass) {
            this.name = name;
            /* 
            제네릭은 타입을 알수 없기 때문에 어쩔수 없이 배열 정보를 얻어오려면 
            만드는 객체자체를 원하는 타입으로 받아와야 함..
            그래서 생성자에 클래스 타입을 받는 방법(Reflection API)으로 해결은 가능하다
            */
            students = (T[]) Array.newInstance(tClass, capacity);
        }
    
        public String getName() {
            return name;
        }
    
        public T[] getStudents() {
            return students;
        }
    
        public void add (T t) {
            for(int i=0;i<students.length;i++) {
                if (students[i] == null) {
                    students[i] = t;
                    break;
                }
            }
        }
    }

    マルチタイプパラメータ


    ジェニーリックタイプは、2つ以上のマルチタイプパラメータを使用できます.
    public class Product<T, M> {
        private T kind;
        private M model;
    }

    ジェニーリックの主な概念


    バインドタイプ(境界タイプ)

    public <T extends 상위타입> 리턴타입 메서드(매개변수, ...) { ... }
    タイプパラメータで指定した特定のタイプを制限できます.上記の例のTタイプ変数は、extendedの親タイプ以下のタイプしか指定できないように制限されています.

    ワイルドカードタイプ(ワイルドカードタイプ)


    Unbounded Wildcards : <?>

  • に制限はありません.すべてのタイプが可能です.と同じ
  • タイプのパラメータに代わる特定のタイプは、すべてのクラスまたはインタフェースタイプであってもよい.
  • Upper Bounded Wildcards : <? extends T>

  • ワイルドカードの上限制限.Tと彼らの子供だけが
  • できる.
  • プレミアム制限
  • Lower Bounded Wildcards : <? super T>

  • ワイルドカードの下限.Tとその両親だけが
  • を使用できます.
  • サブクラス制限

  • 上記のクラス間の継承関係により、ワイルドカードメソッドを詳細に説明します.
    受講生のタイプをJENERICと指定した場合は、次のように指定できます.
    Courseで?「学習者」(Person、Worker、Studio、HighStudio)クラスに入ります.
  • Course
    学習者は、任意のタイプ(Person、Worker、Studio、HighStudio)です.
  • Course
    学習者は学習者と学習者のみになります.
  • Course
    学習者はWorkerとPersonのみです.
  • ジェニーリックの方法


    メソッドの宣言簿で「ジェニーンリックタイプ」と宣言するメソッドを「ジェニーンリックメソッド」と呼ぶ.ジェニーリックメソッドは、メソッドがタイプを返す前に<>記号を追加し、タイプパラメータを記述し、タイプパラメータを戻りタイプとパラメータとして使用します.(Collections.sort()は代表的なGenericメソッドです.)
    static <T> void sort(List<T> list, Comparator<? super T> c)
    JENICメソッドは、JENICクラスではなくクラスに定義できます.
    上記のバインドタイプ、ワイルドカードタイプはいずれも適用できます.
    static <T extends Fruit> Juice makeJuice(FruitBox<T> box) {
        ...
    }

    JENARICタイプの削除(Erasure)


    コンパイラはJENICタイプを使用してソースファイルをチェックし、必要な場所で変換します.
    そしてジェニーリックタイプを除去します.つまり、コンパイルされたファイル(*.class)にはGenericタイプに関する情報はありません.
    これは,Generic導入以前のソースコードとの互換性を保つためである.JDK1.JENICは5から導入されているが,元のタイプでコードを記述することは許可されている.(元のタイプは使用しないでください)

    実際のアンインストールプロセス


    1.ジェニーリックタイプの境界を取り除く.
    の場合、TはFruitに変換されます.の場合、Objectに変換されます.
    class Box<T extends Fruit> { -> class Box
        void add(T t) { -> void add(Fruit T) {
            ...
        }
    }
    2.JENERICタイプを除去した後、タイプが一致しない場合は変形を追加します.
    ワイルドカードが含まれている場合は、適切なタイプの変換も追加されます.
    T get(int i) { -> Fruit get(int i) {
        return list.get(i); -> return (Fruit)list.get(i);
    }
    上記の例では、リストのget()がオブジェクトタイプを返すため、シェイプを変換する必要があります.
    Genericはプログラマーがより簡単に開発できる機能をサポートし、最終的にコンパイラによってすべての形式の変換を行う.
    この文章はJava言語の基礎を築くために書かれたものです.
    この文書のエラーまたは追加する必要がある内容は次のとおりです[email protected]分かち合えばありがたいです
    この記事を参照または転載する場合は、ソースをリンクしてください:)
    リファレンス
    1. 白旗仙-ジャバステディ
    2.これがJava-信用圏を征服するJavaプログラミング
    3.Javaの定式書3 rd Edition
    4. stackoverflow-Generics, arrays, and the ClassCastException
    5. stackoverflow-How to create a generic array? [duplicate]
    6. Java Genericと可変性1編
    7. JAVA JENERICアレイを作成できない理由