Java Genericsを理解する最も簡単な方法は、Javaタイプのキャストの操作を節約できる便利な構文と見なすことです。
リスト<purph> box = ...; Apple Apple = box.get(0);
上記のコード自体が明確に表現されています。BoxはAppleオブジェクトを含むリストです。 GETメソッドはAppleオブジェクトインスタンスを返しますが、このプロセスではタイプ変換は必要ありません。ジェネリックはありません。上記のコードは次のように記述する必要があります。
リストボックス= ...; Apple Apple =(Apple)Box.get(0);
ジェネリックの主な利点は、コンパイラがパラメーターのタイプ情報を保持し、タイプチェックを実行し、タイプ変換操作を実行できるようにすることであることは明らかです。コンパイラは、これらのタイプ変換が完全に正しいことを保証します。プログラマーに依存してオブジェクトタイプを覚えてタイプ変換を実行することと比較してください。これにより、プログラムが実行されると障害が発生します。コンパイラは、プログラマーがコンパイル時に多数のタイプチェックを強制し、エラーを見つけるのに役立ちます。
ジェネリックの構成
ジェネリックの構成は、型変数の概念につながります。 Java言語の仕様によると、タイプ変数は無制限のGlyphの一種であり、次の状況から生じます。
一般的なクラス宣言一般的なインターフェイス宣言一般的な方法宣言一般コンストラクター宣言
一般的なクラスとインターフェイス
クラスまたはインターフェイスに1つ以上のタイプ変数がある場合、それは一般的です。タイプ変数は、角度ブラケットで定義され、クラスまたはインターフェイス名の後に配置されます。
パブリックインターフェイスリスト<t>拡張コレクション<t> {...}簡単に言えば、タイプ変数の役割はパラメーターのようなもので、タイプチェックのためにコンパイラに情報を提供します。
コレクションフレームワーク全体など、Javaクラスライブラリの多くのクラスは、一般的な形式で変更されています。たとえば、上記の最初のコードで使用したリストインターフェイスは、一般的なクラスです。そのコードでは、ボックスはリスト<popple>オブジェクトであり、これはAppleタイプの変数を使用したリストインターフェイスのクラス実装のインスタンスです。コンパイラは、このタイプ変数パラメーターを使用して、呼び出されたときにGETメソッドを自動的に変換し、Appleオブジェクトを返します。
実際、この新たに出現する汎用タグ、またはこのリストインターフェイスのGETメソッドは次のとおりです。
t get(int index);
GETメソッドは、実際にタイプTのオブジェクトを返します。これは、リスト<T>宣言のタイプ変数です。
一般的なメソッドとコンストラクター
非常によく似ていますが、メソッドとコンストラクターで1つ以上のタイプ変数が宣言されている場合、それらは一般的である可能性があります。
public static <t> t getFirst(リスト<t>リスト)
このメソッドは、リスト<t>パラメーターを受け入れ、タイプTのオブジェクトを返します。Javaクラスライブラリで提供される一般的なクラスを使用するか、独自の汎用クラスを使用できます。タイプセーフライティングデータ...次のコードは例です。リスト<string>インスタンスを作成してから、データをロードします。
List <String> str = new ArrayList <String>(); str.add( "hello"); str.add( "world。");
リスト<string>に別のオブジェクトをロードしようとすると、コンパイラがエラーを促します。
str.add(1);
タイプセーフリーディングデータ...
リスト<string>オブジェクトを使用している場合、文字列オブジェクトを取得することが常に保証されます。
文字列mystring = str.get(0);
トラバーサル:Iterator <T>など、クラスライブラリの多くのクラスは機能を強化し、汎用化されています。リスト<t>インターフェイスのIterator()メソッドは、Iterator <T>を返します。 t next()メソッドによって返されるオブジェクトは、タイプ変換する必要はありません。直接正しいタイプを取得します。
for(iterator <string> iter = str.iterator(); iter.hasnext();){string s = iter.next(); system.out.print(s);}foreachを使用すると、「各」構文もジェネリックの恩恵を受けます。前のコードは次のように書くことができます:
for(string s:str){system.out.print(s);}これは読みやすく、メンテナンスが簡単です。
自動カプセル化(オートボクシング)および自動開梱(自動ボクシング)。 Java Genericsを使用する場合、次のコードと同じように、自動ボクシング/オートナーキングの2つの機能が自動的に使用されます。
list <integer> ints = new ArrayList <Integer>(); ints.add(0); ints.add(1); int sum = 0; for(int i:ints){sum += i; }ただし、理解する必要があることの1つは、パッケージングと開梱がパフォーマンスの損失をもたらすことであり、すべての汎用を慎重に使用する必要があることです。
ジェネリックは、Java SE 1.5の新機能です。ジェネリックの本質はパラメーター化されたタイプです。つまり、動作するデータ型はパラメーターとして指定されています。このパラメータータイプは、クラス、インターフェイス、メソッドの作成に使用でき、それぞれ汎用クラス、汎用インターフェイス、および汎用メソッドと呼ばれます。
Java言語でジェネリックを導入する利点は、安全でシンプルであることです。
Java SE 1.5の前に、ジェネリックがなければ、型オブジェクトを参照することにより、パラメーターの「任意」が達成されました。 「arbitrary化」の欠点は、明示的なキャストタイプ変換が必要であることであり、この変換では実際のパラメータータイプを予測する必要がありました。キャストタイプの変換エラーの場合、コンパイラはエラーを促さない場合があり、例外は実行中にのみ発生します。これはセキュリティリスクです。
ジェネリックの利点は、コンパイル時にタイプの安全性をチェックし、すべてのキャストが自動で暗黙的であり、コードの再利用率を改善することです。
ジェネリックの使用にはいくつかのルールと制限があります。
1.汎用型のタイプパラメーターは、単純なタイプではなく、クラスタイプ(カスタムクラスを含む)のみです。
2。同じ汎用型は、複数のバージョンに対応できます(パラメータータイプが不確かであるため)、異なるバージョンの汎用クラスのインスタンスは互換性がありません。
3.ジェネリックには複数のタイプパラメーターがあります。
4.たとえば、汎用パラメータータイプは、拡張ステートメントを使用できます。習慣的に「境界型」になります。
5.一般的なタイプのパラメータータイプは、ワイルドカードタイプでもあります。たとえば、class classtype = class.forname(java.lang.string);
ジェネリックには、多くのコンテンツを含むインターフェイス、メソッドなどもあり、それらを習熟し、習得し、適用するのに多少の努力が必要です。同じ機能を実現できるジェネリック(私が見た印象に基づいて書かれた)について学んだときに書いた2つの例を以下に示します。 1つはジェネリックを使用し、もう1つは使用しません。比較を通じて、ジェネリックの適用をすばやく学ぶことができます。これを学び、基本的にジェネリックのコンテンツの70%を学びます。
例1:ジェネリックが使用されます
パブリッククラスgent {private t ob; // genericメンバー変数public gen(t ob){this.ob = ob; } public t getob(){return ob; } public void setob(t ob){this.ob = ob; } public void showtyep(){system.out.println( "tの実際のタイプは:" + ob.getClass()。getName()); }} public class gendemo {public static void main(string [] args){// generic class gen gen inthb = new Geninteger(88); intob.showtyep(); int i = intob.getob(); System.out.println( "value =" + i); System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------例2:ジェネリックは使用されません
パブリッククラスGen2 {プライベートオブジェクトob; //一般型メンバーpublic gen2(object ob){this.ob = ob; } public object getob(){return ob; } public void setob(object ob){this.ob = ob; } public void showtyep(){system.out.println( "tの実際のタイプは:" + ob.getClass()。getName()); }} public class gendemo2 {public static void main(string [] args){// class gen2 gen2 inteb = new gen2(new integer(88)); intob.showtyep(); int i =(integer)intob.getob(); system.outln( " +" + " +" + i);System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ strob.getob(); system.out.println( "value =" + s)}}実行結果:
2つの例でデモを実行した結果は同じであり、コンソール出力は次のとおりです。
Tの実際のタイプは次のとおりです。
java.lang.integer
値= 88
--------------------------------------------
Tの実際のタイプは次のとおりです。Java.lang.String
value = hello gen!
出口コード0で終了したプロセス
これを理解していれば、基本的なジェネリックアプリケーションとコードの読み取りが将来的には問題になりません。
上記は、Java Genericsの例の例です。 Java Genericsを学ぶ友人はそれを参照できます。