ホームページ >Java >&#&チュートリアル >ジェネリックとリフレクションの使用の概要 - ジェネリック
私の意見では、JDK5.0 は間違いなく画期的なバージョンであり、このバージョンでは多くの貴重な新機能が提供され、ジェネリックスもその 1 つであり、リフレクション メカニズムも強化されています。また、バージョン 5.0 では以前のコレクション フレームワークも再構築されています。汎用サポートを追加しました。
5.0 のリリースからほぼ 10 年が経ち、この点についてはオンラインや書籍でも多くの知識が得られます。エレファントは今、第一に自分自身の経験と経験を要約するために、第二に、この側面に不慣れな子供たちに何らかの助けを与えることを願って、これらのことを書いています。
ジェネリックの最大の利点は型チェックであり、これはコレクションに特に役立ち、再利用が可能になるため、基礎となるコード設計にも非常に役立ちます。ジェネリックスを定義するには 2 つの方法があります。1 つはジェネリック クラスで、もう 1 つはジェネリック メソッドです。
では、ジェネリック医薬品とは一体何でしょうか?簡単に言うと(厳密ではないかもしれませんが)、クラスでもインターフェイスでもメソッドでも、型パラメータなどの型変数を使うことを指します。例を参照してください:
汎用クラス
use ' using 's ' using through using using'' out out out out out out of 's 「 」 スルースルースルーアウトスルーアウトスルースルースルー-- ‐‐‐‐‐ public void setT(T t) {
this.t = t }
}
T はパラメータ化された型であり、山括弧 (< >) をクラス名の後に置きます。ジェネリック クラスには、複数の型変数を定義できます。型変数は通常、大文字で表されます (この例では Person
型変数を具象クラスに置き換えることで、ジェネリック クラスをインスタンス化することができます: person
次のようにインスタンス化するのは間違っています: person
ジェネリック メソッド
public
SSM3 の例で MyBatisDao クラスに定義したメソッドはジェネリック メソッドです。
しかし、これを書き換えて MyBatisDao にジェネリックスを追加すると、パブリック クラス MyBatisDao
その場合、User の戻り値の型でコンパイル エラーが発生します:
ロール型変数 MyBatisDao
型パラメータの制限
上限:
疑問符 (?) ) は無制限のワイルドカードと呼ばれ、任意の型を表すことができます。場合によっては、型変数を使用するのがあまり便利ではない場合がありますが、ワイルドカード型はこの問題をうまく解決します。
super T> T はそれ自身のスーパータイプとみなすことができるため、T 型変数のスーパータイプには T 自体も含まれることがわかります。
では、なぜ extends が上限で extends が下限と言われるのでしょうか?前の 2 つの説明から、extends Serializable または extends T は、型変数が Serializable のサブクラスであり、T 変数のサブタイプである必要があることを示していることは明らかです。これは、型変数の上限を制限することと同じですか?同様に、下限値の意味も理解できます。
上限と下限についてこれまで述べてきましたが、それらは何に役立つのでしょうか?そしてそれをどのように使用するか?簡単に言うと、extends で修飾された型パラメータはジェネリック オブジェクトから読み取ることができ、super で修飾された型パラメータはジェネリック オブジェクトに書き込むことができます。こんなことを言うと失神してしまう子もいるかもしれない。これは一体何を言っているのだろうか?
ジェネリックの上限と下限についての式をまとめました。 PECS は、生産者-拡張、消費者-スーパーを意味します
上記は、パラメーター化された型が生産者を表す場合、< を使用することを意味します。 T> が消費者を表す場合は、
public void add(List extends T> list){
for(T t : list){
} public void add(T t, List super T> list){
List.add(t);
}
ジェネリック消去
ジェネリックは主にコンパイル中に有効です。つまり、コンパイル中に型安全性がチェックされます。現在、コードを記述するときは、一般に Eclipse または IntelliJ を使用して、これらの統合開発ツールをオンザフライでコンパイルできます。エラーがあるとすぐに赤いエラーマークが表示されます。したがって、型変換エラーが発生した場合、結果は明らかです。ただし、プログラムの実行段階では、JVM はジェネリックスがマジックであることを認識しません。ジェネリックスを含むすべてのクラス、インターフェイス、およびメソッドは、そのジェネリックスが消去され、生の型になります。つまり、Person
以下は、前の person クラスを javap で逆コンパイルした結果です。 T は非修飾型であるため、すべての型変数が消去されています。さらに、add メソッドの と も削除されました。
public class com.bolo.person extends java.lang.Object{
private java.lang.Object t;
public com.bolo.Person();
public java.lang.Object getT();
public void setT(java.lang.Object);
public void add(java.util.List);
public void add(java.lang.Object);
public void add(java.lang.Object, java.util. List);
}
したがって、ジェネリック消去の機能に関しては、次の点に注意する必要があります:
1. JVM にはジェネリックはなく、通常のクラスとメソッドのみが存在します。
2. すべての型パラメータは、オブジェクトを使用して制限された型または無制限の型に置き換えられます。
3. メソッドのオーバーロードは注意して扱ってください。オーバーロードを誤って使用すると、目的の多態性が実現されません。
4. 型の安全性を確保するため、必要に応じて強制型変換を使用してください。
ジェネリックの制限
基本型は型パラメータとして使用できません。 person
型変数はインスタンス化できません。これを書くのは間違いです: T t = new T()
パラメータ化された型の配列をインスタンス化することはできません。 Person
静的インスタンス変数と静的メソッドは定義できません。次のように書きたい場合: private static T a その場合、申し訳ありませんが、コンパイラはすぐにエラー メッセージを表示します。
実際、ジェネリックの制限について話す必要はありません。これを実行すると、すぐにエラーが表示されます。
最後に、ジェネリックはコレクションに最も役立ちます。コレクションはコンテナであり、ジェネリックを使用すると再利用が容易になります。最も頻繁に使用するコレクションは List であり、もう 1 つのコンテナーは配列です。Elephant では、List をより使用し、配列は使用しないことを強くお勧めします。 1 つ目は List に型安全性チェックがあること、2 つ目は List が配列のすべての関数を提供し、より豊富であること、3 つ目は List が gc を最適化することです。配列を使用する場合、特にオブジェクト配列を操作する場合、経験が浅く配列内のオブジェクト参照を解放しないと、メモリ リークが発生しやすくなります。