2009-04-19 6 views
5
private ArrayList<String> colors = new ArrayList<String>(); 

上記の例を見ると、ジェネリックの主なポイントはコレクションに型を強制することです。したがって、プログラマの裁量でStringにキャストする必要がある "Objects"の配列を持つ代わりに、ArrayListのコレクションに "String"型を適用します。これは私にとって初めてのことですが、正しく理解していることを確認したいだけです。この解釈は正しいのでしょうか?Javaジェネリックは主にコレクションの要素に静的型を強制する方法ですか?

答えて

1

ええ、それは基本的にそれです。ジェネリックの前に、オブジェクトのArrayListを作成しなければなりませんでした。これは、のいずれかのオブジェクトをリストに追加できることを意味しました。たとえArrayListに文字列が含まれることを意図していたとしてもです。

すべてのジェネリックはタイプセーフです。つまり、JVMはリスト内のオブジェクトがすべてStringであることを確認し、String以外のオブジェクトをリストに追加できないようにします。このチェックはコンパイル時に行われます。

+3

コンパイル時にのみ、実際には型の安全性が実行時に追加されないことに注意してください。実行時に型が破棄され、何かが起こる可能性があります。 Genericsは、ドキュメント/明快さとコンパイル時のチェックのためのものです。 – davetron5000

+1

@ davetron5000 true! Javaはこの「機能」タイプ消去を呼び出します。http://java.sun.com/docs/books/books/tutorial/java/generics/erasure.html 個人的には、私はそれがこれまでで最も厄介なものであると感じています。 – poundifdef

+2

既存のコードとの互換性を損なうことなく、改良されたジェネリックを追加することはできませんでした。 Neal Gafterはこれをかなり徹底的に説明しています:http://gafter.blogspot.com/2006/11/reified-generics-for-java.html –

2

はい、ご理解いただけます。コレクションは指定された型に強く型付けされています。ランタイムキャストはこれ以上ありません。

+0

実行時キャストはまだ行われません(プログラマーから隠されていますか?)。 – jpalecek

+0

jpalecek:いいえ、rascherを引用する - 「さらに良い - このチェックはコンパイル時に実行されます」 –

+0

実行時キャストはまだありますが、一般的なクラスのユーザーとしては、通常は自分で行う必要はありません。 –

1

はい。型の安全性を維持し、ランタイムキャストを削除することが正解です。

0

Java siteのチュートリアルを参照してください。それは導入の良い説明を与える。ジェネリックなし

:ジェネリック

List<Integer> myIntList = new LinkedList<Integer>(); // 1' 
myIntList.add(new Integer(0)); // 2' 
Integer x = myIntList.iterator().next(); // 3' 

List myIntList = new LinkedList(); // 1 
myIntList.add(new Integer(0)); // 2 
Integer x = (Integer) myIntList.iterator().next(); // 3 

私は型の安全性として、それを考えても、鋳造を節約します。 autoboxingについてもっと読む。

+1

オートボクシングでは、置き換えることができます myIntList.add(new Integer(0)); とちょうど myIntList.add(0); これはタイプのないリストでは当てはまりません。 –

8

を参照してください。

ジェネリックは、コレクションだけでなく、静的型の安全性を確保するために、さまざまな場所で使用できます(また使用されます)。

ジェネリックスが有用な場所にあなたが来るので、言いたいことがありますが、ジェネリック/コレクションの関連付けに慣れている場合は、その事実を見落とす可能性があります。

+5

私はこの回答を2番目にしたいです。ほとんどの開発者はコレクションのクラスでまずJavaジェネリックに直面します。これはジェネリックスがコンパイル時の型チェックに大きな改善をもたらす場所です。しかし、一度ジェネリックで考えると多くのパターンが出てきます。例えば。 publicのようなファクトリメソッド T createInstance(Class klass)と同様です。一般的にキャストを行う時間は一般に、ジェネリックでキャストをタイプセーフな式に置き換えることができます。 – ordnungswidrig

0

はい、正しいです。ジェネリックスはプログラムにコンパイル時の型の安全性を追加します。つまり、間違ったタイプのオブジェクトを入れた場合、つまりArrayListにコンパイラが検出できます。

私が指摘したいことの1つは、可視のランタイムキャストを削除し、ソースコードをクラッターしないにもかかわらず、JVMはバックグラウンドでキャストを実行することです。

ジェネリックスがJavaで実装される方法は、キャストを隠すだけで、ジェネリックでないバイトコードも生成します。 ArrayList<String>は依然としてバイトコード内のオブジェクトのArrayListです。これに関する良いことは、バイトコードを以前のバージョンと互換性を保つことです。悪い点は、これが巨大な最適化の機会を逃すことです。

0

タイプのパラメータが必要な任意の場所、つまりコードによっては同じである必要がありますが、多少の不特定になるタイプを使用できます。

たとえば、私のおもちゃプロジェクトの1つは、コンピュータ代数のアルゴリズムをJavaで一般的な方法で記述することです。これは、数学的アルゴリズムのために興味深いですが、ストレステストを通じてJavaジェネリックスを置くこともできます。

このプロジェクトでは、リングやフィールドなどの代数構造やそれぞれの要素、具体的なクラスなどのさまざまなインターフェイスが用意されています。リング上の整数または多項式の場合、リングは型パラメータです。それは動作しますが、場所によってはやや面倒になります。これまでのレコードは、多項式の既約性をテストするためのアルゴリズムで、80文字の2行にまたがる変数の前の型です。主な原因は、複雑な型に独自の名前を付けることができないことです。

関連する問題