ホームページ  >  記事  >  Java  >  Java の extends T と super T とは何ですか?

Java の extends T と super T とは何ですか?

PHPz
PHPz転載
2023-05-09 11:19:171313ブラウズ

? ワイルドカード型

  • ##d203bb1ae585225d4838a2b7e3d0503e は型の上限を示し、パラメーター化された型が T または T のサブクラスである可能性があることを示します;

  • 117c5a0bdb71ea9a9d0c2b99b03abe3e は型の下限 (Java Core ではスーパー型修飾と呼ばれます) を表し、パラメータ化された型がこの型のスーパー型 (親型) であることを Object まで示します。

上限9b28e91af246b3d878e5ce4186e6a9d1

に対して未定義です

List3f622c4eabd1145a5b9f71573034350b は、「Son から継承された任意の型を持つリスト」を意味し、コンパイラは List が保持する型を判断できないため、リストにオブジェクトを安全に追加できません。 null は任意の型を表すことができるため、null を追加できます。したがって、List の add メソッドは意味のある要素を追加できませんが、既存のサブタイプ List の割り当ては受け入れることができます。

これを実行してみてください:

List<? extends Father> list = new LinkedList<Son>();
list.add(new Son());

Son 型を指定した場合でも、add メソッドを使用して Son オブジェクトを追加することはできません。 Father クラスと Father クラスのサブクラスを

リストに追加できないのはなぜですか? それを分析してみましょう。

List3f622c4eabd1145a5b9f71573034350b は、上限が Father であり、次の代入が正当であることを意味します

   List<? extends Father> list1 = new ArrayList<Father>();
   List<? extends Father> list2 = new ArrayList<Son>();
   List<? extends Father> list3 = new ArrayList<LeiFeng>();

If List3f622c4eabd1145a5b9f71573034350b は、add メソッドをサポートします:

list1 は Father と Father のすべてのサブクラスを追加できます;
  • list2 は Son と Son のすべてのサブクラスを追加できます;
  • list3 は LeiFeng とすべての LeiFeng サブクラスを追加できます。
  • 次のコードはコンパイルに合格しません:
  • list1.add(new Father());//error
    list1.add(new Son());//error
その理由は、コンパイラーはコンテナーがファーザーまたはその派生クラスであることのみを認識しており、認識していないためです。特定のタイプ。もしかして父さん?もしかして息子さん?もしかしたらレイフェン、シャオミン?後で代入に Father が使用されることをコンパイラーが認識すると、コレクション内のパラメーターの型は「Father」に限定されなくなります。代わりに、プレースホルダーでマークされています: CAP#1 は、ファーザーまたはファーザーのサブクラスをキャプチャしていることを示します。特定のクラスはわかりませんが、コードは CAP#1 です。次に、Son、LeiFeng、または Father コンパイラを挿入するかどうかは、この CAP#1 に一致するかどうかわからないため、許可されません。

ワイルドカード 6b3d0130bba23ae47fe2b8e8cddf0195 と型パラメーターの違いは、コンパイラーにとって、すべての T が同じ型を表すことです。たとえば、次の汎用メソッドでは、3 つの T はすべて同じ型 (String または Integer) を参照しています。

public <T> List<T> fill(T... t);

しかし、ワイルドカード 6b3d0130bba23ae47fe2b8e8cddf0195 にはそのような制約はありません。List6b3d0130bba23ae47fe2b8e8cddf0195 は単に、コレクション内に何かがあるが、それが何であるかわからないことを意味します。

つまり、ここでのエラーは、List3f622c4eabd1145a5b9f71573034350b には何も入れられないということです。

List3f622c4eabd1145a5b9f71573034350b list は追加できませんが、このフォームは依然として非常に便利です。add メソッドは使用できませんが、Season は初期化中にさまざまなタイプを指定できます。例:

List<? extends Father> list1 = getFatherList();//getFatherList方法会返回一个Father的子类的list

さらに、親クラスまたはそのサブクラスの 1 つが List に格納されていることを確認したため、get メソッドを使用して値を直接取得できます:

List<? extends Father> list1 = new ArrayList<>();
Father father = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
Object object = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
Human human = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
Son son = (Son)list1.get(0);

下限< ;? super T> は格納には影響しませんが、取得は Object オブジェクトにのみ配置できます。

下限は super で宣言され、パラメータ化された型が指定された型である可能性があることを示します。またはこのタイプの親タイプ (オブジェクトまで)。

//super只能添加Father和Father的子类,不能添加Father的父类,读取出来的东西只能存放在Object类里
List<? super Father> list = new ArrayList<>();
list.add(new Father());
list.add(new Human());//compile error 
list.add(new Son());
Father person1 = list.get(0);//compile error 
Son son = list.get(0);//compile error 
Object object1 = list.get(0);

下限は要素の最小粒度の下限を指定するため、実際にはコンテナ要素の型制御が緩和されます。この要素はFatherの基底クラスであるため、Fatherよりも小さい粒度で格納できます。型安全性の理由から、Father オブジェクトまたはそのサブクラス (Son など) を追加できますが、コンパイラは List の内容が Father のどのスーパークラスであるかを認識しないため、特定のスーパークラスを追加することはできません。 . クラス (人間など)。 Object は Java クラスの最終的な祖先クラスであるため、これを読み取ると、コンパイラはその型を認識せずに Object オブジェクトのみを返すことができます。ただし、この場合、要素の型情報はすべて失われます。

PECS 原則

最後に、PECS (Producer Extends Consumer Super) 原則とは何かを見てみましょう。これはすでによく理解されています:

# 頻繁に外部から読み込むコンテンツの場合は、上限拡張を使用するのが適しています。

  • 頻繁に入れるならネザースーパーが適しています。

以上がJava の extends T と super T とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。