Java のジェネリックスを詳しく見る

零下一度
リリース: 2017-07-18 09:47:09
オリジナル
1499 人が閲覧しました

ジェネリックの定義: ジェネリックはJDK 1.5の新機能であり、その本質はパラメータ化された型(Parameterized Type)の適用であり、操作されるデータ型が次のように指定されることを意味します。パラメータ 、使用時に特定のタイプを指定します。このパラメータ タイプは、それぞれジェネリック クラス、ジェネリック インターフェイス、ジェネリック メソッドと呼ばれるクラス、インターフェイス、およびメソッドの作成に使用できます。

ジェネリックの考え方は、早くも C++ 言語のテンプレートに根付き始めました。Java 言語がジェネリックがまだ登場していないバージョンだったとき、メソッドは Object の親クラスだけでした。すべての型と型キャスト機能を組み合わせて型の一般化を実現します。たとえば、ハッシュ テーブルのアクセスでは、JDK 1.5 より前では HashMap の get() メソッドが使用されていました。Java 言語のすべての型は java.lang.Object を継承しているため、Object は次のようになります。成都はあらゆるオブジェクトに変換できます。ただし、可能性は無限にあるため、このオブジェクトがどのタイプのオブジェクトであるかを知るのはプログラマとランタイム仮想マシンだけです。コンパイル中に、コンパイラは、このオブジェクトの強制変換が成功したかどうかを確認できません。この操作の正確性をプログラマのみに依存している場合、ClassCastException の多くのリスクがプログラム ランタイムに伝達されます。 C# と Java でのジェネリック テクノロジの使用は同じように見えますが、プログラム ソース コード、中間言語、中間言語、中間言語の実装において根本的な違いがあります。 、言語、現時点では、ジェネリックはプレースホルダーです)、または、List と List は、システム実行時に生成される 2 つの異なるタイプです。独自の仮想メソッド テーブルと型データ、この実装は型インフレーションと呼ばれ、このメソッドに基づいて実装されたジェネリックスは真のジェネリックスと呼ばれます。

Java 言語のジェネリックは異なり、コンパイルされたバイトコード ファイル内にのみ存在し、元の​​ raw タイプ (Raw Type、ネイキッド タイプとも呼ばれます) に置き換えられ、キャスト コードが挿入されます。したがって、実行時の Java 言語では、ArrayList と ArrayList は同じクラスになります。したがって、ジェネリック技術は実際には Java 言語の構文糖体であり、Java 言語におけるジェネリック実装メソッドは型消去と呼ばれ、このメソッドに基づいて実装されたジェネリックスは擬似ジェネリックスと呼ばれます。 (型消去については後で検討します)


汎用メカニズムを使用して書かれたプログラムコードは、オブジェクト変数を乱雑に使用して強制的に型変換を実行するコードよりも安全で読みやすいです。ジェネリックはコレクション クラスで特に便利です。

1. ジェネリックスを使用する理由

ここでコードの一部を見てみましょう。

List list = new ArrayList();  
list.add("CSDN_SEU_Cavin");  
list.add(100);  
for (int i = 0; i < list.size(); i++) {  
  String name = (String) list.get(i); //取出Integer时,运行时出现异常  
System.out.println("name:" + name);  
}
ログイン後にコピー

この例では、文字列型の値と整数型の値をリスト型コレクションに追加します。 (リストのデフォルトのタイプはオブジェクトであるため、これは正当です)。後続のループでは、リストに Integer 型の値を追加する前に追加し忘れたり、その他の理由により、実行時に java.lang.ClassCastException 例外が発生します。この問題を解決するためにジェネリック医薬品が登場しました。

2. ジェネリックの使用 ジェネリックを使用すると、プログラマーは通常コレクションで使用される型の抽象化を使用できます。

List<String> list = new ArrayList<String>();
ログイン後にコピー

こう書くと、上記のループ値取得メソッドはエラーを報告せず、型変換を行う必要もありません。 List により、リスト コレクションには String 型の要素のみを含めることが直接制限されます。

3. ジェネリックはコンパイル中にのみ有効です ジェネリックを使用するときは、ジェネリックがコンパイルされるときに何が起こるかを理解する必要もあります。そのため、ここでは次の点に特別な注意を払う必要があります。コードがクラスファイルにコンパイルされたときに有効です

AyyayList<String> a = new ArrayList<String>();  
ArrayList b = new ArrayList();  
Class c1 = a.getClass();  
Class c2 = b.getClass();  
System.out.println(a == b);
ログイン後にコピー

上記プログラムの出力結果はtrueです。これは、すべてのリフレクション操作が実行時に実行されるためです。これは、コンパイル後にプログラムが非ジェネリック化措置を講じることを証明します。

つまり、Javaのジェネリックスはコンパイル段階でのみ有効です。コンパイル プロセス中に、ジェネリックの結果が正しく検証された後、ジェネリックの関連情報が消去され、型チェックと型変換メソッドがオブジェクトのエントリ メソッドと終了メソッドの境界に追加されます。言い換えれば、

正常にコンパイルされたクラスファイルには一般的な情報は含まれていません。一般的な情報は実行時フェーズに入りません

次のコードは、ジェネリックがコンパイル中にのみ有効であることを Java のリフレクション メカニズムを通じてよく説明しています

ArrayList<String> a = new ArrayList<String>();  
a.add("CSDN_SEU_Cavin");  
Class c = a.getClass();  
try{  
    Method method = c.getMethod("add",Object.class);  
    method.invoke(a,100);  
    System.out.println(a);  //[CSDN_SEU_Cavin, }catch(Exception e){  
    e.printStackTrace();
ログイン後にコピー

ジェネリック クラスとジェネリック メソッド

public static class FX<T> {  
    private T ob; // 定义泛型成员变量  
  
    public FX(T ob) {  
        this.ob = ob;  
    }  
  
    public T getOb() {  
        return ob;  
    }  
  
    public void showTyep() {  
        System.out.println("T的实际类型是: " + ob.getClass().getName());  
    }  
}  
    public static void main(String[] args) {  
        FX<Integer> intOb = new FX<Integer>(100);  
        intOb.showTyep();  
        System.out.println("value= " + intOb.getOb());  //java.lang.Integer  System.out.println("----------------------------------");  
  
        FX<String> strOb = new FX<String>("CSDN_SEU_Calvin");  
        strOb.showTyep();  
        System.out.println("value= " + strOb.getOb());  //value= 100 } 
  
ログイン後にコピー

5.ジェネリックの利点

(1) 型安全性。

ジェネリックを使って定義された変数の型制限を知ることで、コンパイラはJavaプログラムの型安全性をより効果的に向上させることができます。

(2)強制的な型変換を排除する。

ソースコード内の多くのキャストを削除します。これにより、コードが読みやすくなり、エラーの可能性が減ります。すべてのキャストは自動的かつ暗黙的に行われます。

(3)パフォーマンスの向上

以上がJava のジェネリックスを詳しく見るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!