汎用ワイルドカードのPECS

2927 ワード

目次
基礎知識点
上限ワイルドカード 
Listにおける上限ワイルドカードのadd()メソッド
Listにおける上限ワイルドカードのget()メソッド
下限ワイルドカード
List中下限ワイルドカードのadd()メソッド
List中下限ワイルドカードのget()メソッド
基礎知識点
        まず、基礎知識点について説明します.
        Javaでは、アップシフトは許可されていますが、ダウンシフトではコンパイルできません.強回転するとClassCastException異常が放出される可能性があります.では、本当に下に転換するには、普段からinstanceofでこのタイプかどうかを判断し、もしそうであれば、強転を行うのが一般的です.
        くだらないことは言わないで、コードをつけます:
class A {
}

class B extends A {
}

class C extends B {
}

上限ワイルドカード 
        上限ワイルドカード:?extends B  ,あるタイプの親がB(または、あるタイプがBに継承されている)であることを示し、クラスのextendと同じです.
Listにおける上限ワイルドカードのadd()メソッド
        リストに何らかのタイプのオブジェクトを入れる役割を果たします.次のコードブロックコードでは、このタイプはBのサブクラスタイプに違いありません.
List extends B> extendList = new ArrayList<>();
extendList.add(new Object());//    
extendList.add(new A());//    
extendList.add(new B());//    
extendList.add(new C());//    
extendList.add(null); //    ,  null         。

        なぜadd(null)以外はコンパイルできないのですか?        コンパイラはextendListがBのサブクラスを入れるべきだとしか知らないので、Bのどのサブクラスを入れるか分からない.つまり、Bに1万個のサブクラスがあれば、あるタイプに1万個のタイプがある可能性があり、その場合はそのタイプが具体的であるとは判断できません.コンパイラはBのどのサブクラスなのか分からないためaddメソッドを実行する際に、ある指定のクラスにタイプ変換してListに入れることができないためnullのみを入れることができ、他のオブジェクトを入れることができない.        なぜObjectもだめなのかと言う人もいるかもしれません.Objectはすべてのクラスの親であるが,ダウンシフトも通常はコンパイルに失敗するため,入れることもできない.
Listにおける上限ワイルドカードのget()メソッド
        あるタイプのListメソッドからあるタイプの値を返す責任を負います.次のコードブロックでは、このタイプがBのサブタイプであり、javaでのアップコンバートが許可されているため、タイプがBとその親タイプの値(例えば、Aタイプ、およびすべてのクラスの親Object)を返すことができます.ただし、コンパイラは、Bタイプのどのサブクラスであるかを決定することはできません.したがって、Bタイプが1つのサブクラスCのみであっても、Cタイプのオブジェクトを直接返すことはできません(強く回転しない限り).
注意:PECSのPE、すなわちproduceです  ->  extend  ,次のコードはリストが生産者であることを示しており、このリストから外に出すしかありません.
List extends B> extendList = new ArrayList<>();
B b = extendList.get(0);//  
A a = extendList.get(0);//      
C c = extendList.get(0);//    

下限ワイルドカード
        下限ワイルドカード:?super B  ,あるタイプがBの親であることを示し、コードで親メソッドを呼び出すsuperキーワードと似ています.
List中下限ワイルドカードのadd()メソッド
        リストに何らかのタイプのオブジェクトを入れる役割を果たします.次のコードブロックコードでは、このタイプはBの親タイプに違いありません.
        注意:PECSのCS、consumerです.  ->  super、次のコードでは、このリストの集合が消費者であることを示しています.中に入れるしかありません.
List super B> superList = new ArrayList<>();
superList.add(new Object());//    
superList.add(new A());//    
//       B    ,      B B   ,      
superList.add(new B());
superList.add(new C());
superList.add(null); //    ,  null         。

        なぜこのList super B>はaddメソッドを実行できるのでしょうか.        コンパイラはBのすべての親を知ることができますが、このタイプがBのどの親タイプなのかを知ることはできません.そのため、BとBの子タイプを入れることができます(アップグレード).
List中下限ワイルドカードのget()メソッド
        コンパイラは、返されるタイプが分からず、Bタイプの親であることしか知らないため、すべてのクラスの親であるため、1つのObjectしか返されません.
Object object = superList.get(0);//  
A a1 = superList.get(0);//    
B b1 = superList.get(0);//    
C c1 = superList.get(0);//