Java -- ジェネリックス

Jun 27, 2017 am 09:13 AM
ジェネリック

型パラメータ

ジェネリック クラスを定義する場合、または ジェネリック クラスの変数を宣言する場合、山括弧を使用して仮型パラメータを指定します。仮型パラメーターと実際の型パラメーターの関係は、型パラメーターが値ではなく型を表すことを除いて、仮メソッド パラメーターと実際のメソッド パラメーターの関係に似ています。

名前付き型パラメーター

推奨される命名規則は、型パラメーターには大文字の 1 文字の名前を使用することです。これは C++ の規則 (付録 A: C++ テンプレートとの比較を参照) とは異なり、ほとんどの generic クラスが少数の型パラメーターを持つという仮定を反映しています。一般的な ジェネリック パターンの場合、推奨される名前は次のとおりです:

K - キー (マップされたキーなど)。
V —— List や Set の内容、または Map 内の値などの値。
E——例外クラス。
T —— 一般的

方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。
ログイン後にコピー

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

1. 入れることができる要素に制限はありません。2 つの異なるオブジェクトを入れると例外が発生する可能性があります。

2. オブジェクトをコレクションに投げます。コレクションはオブジェクトを保持していることだけを知っているため、通常はコレクション要素を取り出した後、強制変換を実行する必要があります。

2 .ジェネリックとは何ですか

Javaのパラメータ化された型はジェネリックと呼ばれ、コレクションを作成するときにプログラムがコレクション要素の型を指定できるようにします

3. ダイヤモンド構文ジェネリックスの

必要なのはその後にダイヤモンド括弧のペアだけです。ジェネリックスを持ってくる必要はありません

4. ジェネリック宣言を使用してカスタム クラスを作成します。 class、construct デバイス名は元のクラス名のままなので、ジェネリック宣言を追加しないでください。

5. ジェネリック クラスからサブクラスを派生する場合、継承時に親クラスの実際のパラメータを渡す必要があります

public class A extends Apple{}

親クラスをオーバーライドするすべてのメソッドは、対応する型になります

実際のパラメータを渡さないこともできます

public class A extends Apple{}

オブジェクト型として

6. ジェネリック クラスはありません

ジェネリックの実際の型パラメータが何であっても、実行時には常に同じクラスを持ちます。どのタイプの実パラメータがジェネリックの type パラメータに渡されるかに関係なく、( は Java のジェネリックの概念の目的にあり、そのため、ジェネリックはコードのコンパイル フェーズでのみ機能します。コンパイル プロセス中に、ジェネリックを正しくチェックする必要があります。型の結果の後、ジェネリック情報は消去されます。つまり、正常にコンパイルされたクラス ファイルにはジェネリック情報が含まれません。Java の実行フェーズには入りません )。一般に、これらは同じクラスとして扱われ、メモリ内のメモリ空間を占有するため、静的メソッド、静的初期化ブロック、または静的変数の宣言と初期化では型パラメータを使用することはできません

説明:

静的変数は、ジェネリック クラスのすべてのインスタンスによって共有されます。 MyClass として宣言されたクラスの場合、そのクラス内の静的変数にアクセスするメソッドは依然として MyClass.myStaticVar です。オブジェクトが new MyClass または new MyClass のどちらによって作成されたかに関係なく、それらはすべて静的変数を共有します。型パラメーターが静的変数の型として許可されると仮定します。次に、次の状況を考えてみましょう。

MyClass クラス 2 = new MyClass();

class1.myStaticVar = "hello";

class2.myStaticVar = 5;

ジェネリックシステムによるタイプ消去。 myStaticVar が Object 型に復元され、その後 class1.myStaticVar= "hello"; が呼び出されると、コンパイラは強制的な型変換を実行します。つまり、myStaticVar = (String)"hello"; が実行されると、呼び出されると、コンパイラは強制的な型変換を実行し続けます。 , myStaticVar = (Integer)Integer.valueOf(5); この時点では、当然、このステートメントは実行時に ClassCastException をスローします。タイプの安全性の問題。したがって、ジェネリック システムでは、クラスの静的変数が型パラメーターを変数の型として使用することはできません。

ジェネリック クラスは実際にはシステム内で生成されないため、インスタンスOD 演算子の後にはジェネリック クラスがまったく存在しないため、使用できません。

7. ワイルドカードを入力します Foo が Bar のサブタイプであり、G がジェネリック宣言を持つクラスまたはインターフェイスである場合、G は G ではないことに注意してください。 。

List が論理的に List の親クラスとみなせると仮定すると、a.test(list) にはエラー プロンプトが表示されず、getData( によって問題が発生します。 ) メソッドがデータを取得するときの型は何ですか?整数か、それともオブジェクトか?また、プログラミングの順序は制御できないため、必要に応じて型判定や強制的な型変換を行う必要があります。明らかに、これはジェネリックの概念と矛盾します。したがって、論理的には、ListList

の親クラスと見なすことはできません。ジェネリック コレクションの親クラスは、型ワイルドカードを使用できます。型ワイルドカードは、任意の型に一致する疑問符です。 型ワイルドカードは、通常、特定の型引数の代わりに ? を使用します。ここにあるのは型パラメータではなく、実際の型パラメータであることに注意してください。そして List は論理的に List、List

>... およびすべての List<具体的な型の実パラメータ> の親クラスです。これからも、そのような要件を満たす汎用メソッドを定義できます。

リストの実際の型が何であっても、それには Object が含まれます注: ワイルドカードは、それがさまざまなジェネリック コレクションの親クラスであることを意味するだけであり、それに要素を追加することはできません

C コレクション内の要素の型が不明なため、オブジェクトを追加できません

7.1 ワイルドカードの上限を設定します

List が List< ではないため;Shape>son 型のため、コンパイルエラー

このリサイクルでは、制限された汎用ワイルドカードを使用できます

7.2 型パラメータの上限を設定します

8。一般的なメソッド

メソッドを定義するときは、マルチスレッドを考慮せずに、同時に

の型パラメータを使用しません。は初期化されて一度呼び出されるため、重複した初期化や不正な呼び出しは発生せず、データベース内のダーティなデータを読み取るような状況も発生しないため、強制的な型変換でコード エラーが発生することはありません。

メソッド宣言で定義された仮パラメータは、このメソッド内でのみ使用できます。

クラスやインターフェイスとは異なり、メソッドのジェネリックスは渡される実際の型パラメータを示す必要はありません

どの型を渡すかについてコンパイラが混乱しないようにしてください

たとえば、test Collection

String 型または Object 型を渡します。コンパイラは T を a, Collection を使用すると、クラスをジェネリック化できます。メソッドが定義されているクラスがジェネリックであるかどうかに関係なく、メソッドをジェネリック化することもできます。

ジェネリック クラスは、複数のメソッド シグネチャにわたって型制約を強制します。 List では、型パラメータ V が get()、add()、contains() などのメソッドのシグネチャに現れます。 Map 型の変数を作成するときは、メソッド間の型制約を宣言します。 add() に渡す値は、get() によって返される値と同じ型になります。

同様に、ジェネリック メソッドを宣言する理由は、通常、メソッドの複数のパラメーター間の型制約を宣言するためです。たとえば、次のコードの ifThenElse() メソッドは、最初のパラメータのブール値に応じて 2 番目または 3 番目のパラメータを返します。 T Second) {

return b ? first : Second;

}

T の値を明示的に指定せずに ifThenElse() を呼び出すことができることに注意してください。コンパイラは、T がどのような値を持つかを明示的に伝える必要はありません。値がすべて同じでなければならないことだけを知っています。コンパイラでは、型推論を使用して、T に置換された String がすべての型制約を満たしていると推定できるため、次のコードを呼び出すことができます。 ;

同様に、次のように呼び出すことができます:

Integer i = ifThenElse(b, new Integer(1), new Integer(2));

ただし、必要な型制約を満たす型がないため、コンパイラーは次のコードを許可しません。

String s = ifThenElse(b, "pi", new Float(3.14));

型 T をクラス定義に追加する代わりに、ジェネリック メソッドを使用することを選択したのはなぜですか?これを行う必要があるケースは (少なくとも) 2 つあります:

ジェネリック メソッドが静的である場合、この場合クラス型パラメーターは使用できません。

T の型制約がメソッドに対して真にローカルである場合、同じクラスの別のメソッド シグネチャで使用されている同じ型 T には制約が存在しないことを意味します。閉じた型のシグネチャは、ジェネリック メソッドの型パラメーターをメソッドに対してローカルにすることで簡素化できます。


制限された型

前の画面のジェネリックメソッドの例では、型パラメーター V は制約なしまたは制約なしの型です。型パラメーターが完全に指定されていない場合、型パラメーターに追加の制約を指定することが必要になる場合があります。

Number クラスによって制限される型パラメーター V を使用する Matrix クラスの例を考えてみましょう。 コンパイラでは、Matrix 型または Matrix 型の変数を作成できますが、Matrix 型の変数を定義しようとすると、エラーが発生します。型パラメーター V は、 Number によって制限されるように評価されます。型の制限がない場合、型パラメーターはオブジェクトによって制限されているとみなされます。前の画面の例「ジェネリック メソッド」では、コンパイラが型パラメーター V の型を認識していなくても、List で呼び出されたときに List.get() が Object を返すことができるのはこのためです。

9. ジェネリックメソッドと型ワイルドカードの違い

仮パラメータ (a) の型またはメソッドの戻り値の型が別の仮パラメータ ( b) type の場合、仮パラメータ (b) の型宣言ではワイルドカードを使用しないでください。メソッド シグネチャで宣言された型パラメータ、つまりジェネリック メソッドのみが考慮されます。

私が理解しているのは、型ワイルドカードはコレクション内の要素を追加または変更する必要がなく、型ワイルドカードを使用すると、他の要素に付加されるのではなく、他の要素に付加されるということです。メソッド シグネチャは、変数の型を定義するためにも使用できます。ジェネリック メソッドの型パラメーターは、対応するメソッドで明示的に宣言する必要があります。

10. 消去と変換

ジェネリック情報を持つオブジェクトをジェネリック情報のない別の変数に代入する場合、山かっこ内のすべての型情報が破棄されます。

li を List に代入すると、コンパイラーは前者の汎用情報を消去します。つまり、リスト コレクション内の要素の型情報が失われます。

Java では、リスト オブジェクトを List 変数に直接割り当てることもできるため、プログラムをコンパイルして渡すことはできますが、発行されるのは 「未チェック変換」 (論理親クラスを子クラスに直接割り当てる) だけです。 ただし、list 変数は実際には list コレクションを参照しているため、コレクション内の要素を String 型オブジェクトとして取り出そうとすると、実行時例外がスローされます

11。

Java ジェネリックには非常に重要な設計原則があります。コードの一部がコンパイル時に「未変換の例外」警告を生成しない場合、プログラムはすべての配列要素の型で ClassCastException 例外を引き起こしません。無制限の型ワイルドカードでない限り、型変数または型パラメーターを含めることはできませんが、型変数または型パラメーターの配列を含むように要素の型を宣言することはできます

それが合格すると仮定すると、警告は発生しませんが、例外がスローされます

次の形式に変更します:

最初の行には「未チェックの変換」警告が表示され、最後の行にも例外がスローされます

キャップなしのワイルドカード ジェネリック 配列

はコンパイル時に警告を発行しませんが、プログラムは lsa の最初の配列要素の最初のコレクション要素を String 型に強制する必要があるため、実行時に例外がスローされます。プログラムは、データ型を保証するために、instanceof 演算子を渡す必要があります

同様に、要素の型が型変数である配列オブジェクトを作成すると、コンパイル エラーが発生します

T[] makeArray(Collection ; coll)

{ return new T[cool.size()]

}

型変数は実行時に存在せず、コンパイラーは実際の型を判断できません

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

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

ジェネリック関数は Golang の可変長引数の型の問題を解決しますか? ジェネリック関数は Golang の可変長引数の型の問題を解決しますか? Apr 16, 2024 pm 06:12 PM

Go のジェネリック関数は、可変個引数型の問題を解決します。ジェネリック関数を使用すると、実行時に型パラメータを指定できます。これにより、さまざまな型のパラメータを処理できる関数を作成できるようになります。たとえば、Max 関数は、2 つの同等のパラメーターを受け取り、大きい方の値を返す汎用関数です。ジェネリック関数を使用すると、さまざまな種類のパラメーターを処理できる、より柔軟で汎用的なコードを作成できます。

golang でのジェネリックスの具体的なアプリケーション シナリオ golang でのジェネリックスの具体的なアプリケーション シナリオ May 04, 2024 am 11:45 AM

Go でのジェネリックスのアプリケーション シナリオ: コレクション操作: フィルター処理など、あらゆるタイプに適したコレクション操作を作成します。データ構造: キュー、スタック、マップなどの汎用データ構造を作成して、さまざまな種類のデータを保存および操作します。アルゴリズム: さまざまな種類のデータを処理できる、並べ替え、検索、リダクションなどの汎用アルゴリズムを作成します。

Java関数ジェネリックの上限と下限は何ですか?使い方? Java関数ジェネリックの上限と下限は何ですか?使い方? Apr 26, 2024 am 11:45 AM

Java 関数ジェネリックでは、上限と下限を設定できます。 Extends は、関数によって受け入れられるか返されるデータ型が、指定された型のサブタイプである必要があることを指定します。下限 (スーパー) は、関数によって受け入れられるか返されるデータ型が、指定された型のスーパータイプである必要があることを指定します。ジェネリックを使用すると、コードの再利用性とセキュリティが向上します。

Golang でのジェネリックの利点と使用法を調べる Golang でのジェネリックの利点と使用法を調べる Apr 03, 2024 pm 02:03 PM

回答: Golang ジェネリックは、コードの再利用性、柔軟性、型安全性、およびスケーラビリティを向上させるための強力なツールです。詳細な説明: 利点: コードの再利用性: 共通のアルゴリズムとデータ構造 柔軟性: 特定の型のインスタンスのランタイム作成 型安全性: コンパイル時の型チェック 拡張性: 拡張およびカスタマイズが容易 目的: 共通の関数: 並べ替え、比較 リストなどの共通のデータ構造、マップ、スタックなど。型エイリアス: 型宣言を簡素化します。制約されたジェネリックス: 型安全性を確保します。

Golang の汎用関数の制限は何ですか? Golang の汎用関数の制限は何ですか? Apr 16, 2024 pm 05:12 PM

Go 汎用関数の制限: 型パラメーターのみがサポートされ、値パラメーターはサポートされません。関数の再帰はサポートされていません。型パラメータは明示的に指定できず、コンパイラによって推論されます。

Android開発におけるJavaジェネリックの適用 Android開発におけるJavaジェネリックの適用 Apr 12, 2024 pm 01:54 PM

Android 開発におけるジェネリックの適用により、コードの再利用性、セキュリティ、柔軟性が強化されます。この構文は、型パラメーター化されたデータの操作に使用できる型変数 T の宣言で構成されます。動作中のジェネリックにはカスタム データ アダプターが含まれており、アダプターがあらゆる種類のカスタム データ オブジェクトに適応できるようになります。 Android は、さまざまな型のパラメーターを操作できる汎用リスト クラス (ArrayList など) と汎用メソッドも提供します。ジェネリックスを使用する利点には、コードの再利用性、セキュリティ、柔軟性が含まれますが、コードの可読性を確保するために正しい境界を指定し、適度に境界を使用するように注意する必要があります。

Golang ジェネリックは関数のシグネチャとパラメーターにどのような影響を与えますか? Golang ジェネリックは関数のシグネチャとパラメーターにどのような影響を与えますか? Apr 17, 2024 am 08:39 AM

Go 関数のシグネチャとパラメーターに対するジェネリックスの影響には、以下が含まれます。 型パラメーター: 関数シグネチャーには、関数が使用できる型を指定する型パラメーターを含めることができます。型制約: 型パラメーターには、満たさなければならない条件を指定する制約を設定できます。パラメーターの型の推論: コンパイラーは、指定されていない型パラメーターの型を推論できます。型の指定: パラメーターの型を明示的に指定して、ジェネリック関数を呼び出すことができます。これにより、コードの再利用性と柔軟性が向上し、複数の型で使用できる関数や型を作成できるようになります。

golang の変数パラメータはジェネリック関数で使用できますか? golang の変数パラメータはジェネリック関数で使用できますか? Apr 29, 2024 pm 02:06 PM

Go では、可変パラメーターをジェネリック関数に使用できるため、可変数のパラメーターを受け入れ、複数の型に適したジェネリック関数を作成できます。たとえば、指定されたリスト内で最も頻繁に出現する要素を検索する汎用関数 Mode を作成できます。Mode は、型 T の可変数の要素を受け入れます。各要素のカウントを作成することで要素をカウントします。次に、最も多く出現する要素を見つけて、それをモードとして返します。 main 関数では、文字列のリストと整数のリストに対して Mode 関数を呼び出すことができます。これにより、それぞれ最も多く出現する文字列と数値が返されます。

See all articles