汎用-タイプワイルドカード
14551 ワード
タイプワイルドカード:ええと、はっきり言って一つですか.の集合が何らかのデータ型であると判断した場合、
Javaコレクションフレームワークでは、パラメータ値が不明なタイプ(すなわち「?」を使用します.ワイルドカード)のコンテナクラスは、コンパイラがその具体的なタイプを予知できないため、読み取りのみ、削除はできませんが、NULLは例外です.
次のコードのようにコンパイルエラーが発生します
listは境界のないワイルドカードを定義し、未知のタイプのlにタイプStringのデータを加えると、コンパイラはエラーを報告しますが、nullを加えるとエラーは報告されません.
1.サブクラス限定ワイルドカード:
2.スーパークラス限定ワイルドカード:
3.PECS原則PECS全文は「Producer Extends,Consumer Super」であり、生産者としてextends、消費者としてsuperを使用することを意味する.
わかるよadd()生産者の動作として集合にStringタイプのデータを追加すると、コンパイラはjavaに不確定なタイプが集合に加わることが許されないため、>Integerのサブクラスとして、このときコンパイラはfeがaddに入れられる具体的なサブタイプを知らない.そのため、エラーが報告されます(子クラスは親とは異なる形態を持っている可能性があるので、ルールを限定せずに、勝手にいろいろな子クラスを追加すると、リストの内容を読み取るときにエラーが発生します.Javaはいっそルールを前に限定しているからです).消費者の操作を行う場合、fsはデータを巡回する際、データ型>IntegerまたはIntegerの親であるため、>は具体的にどのタイプなのか分からないため、コンパイラがエラーを報告する.PECSの最大の原则は生产操作でも消费操作でも、コンパイラに具体的な操作のタイプが何なのかを知らせなければならないので、そうしないと耻ずかしくて、あげません!!
上記の例からルールを整理することができます.
List
と書くことができ、集合がどのタイプであるかを確定しない場合、List>
と書くことができます.Javaコレクションフレームワークでは、パラメータ値が不明なタイプ(すなわち「?」を使用します.ワイルドカード)のコンテナクラスは、コンパイラがその具体的なタイプを予知できないため、読み取りのみ、削除はできませんが、NULLは例外です.
次のコードのようにコンパイルエラーが発生します
public class Test6 {
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
Test6.show(list);
}
public static void show(List<?> list){
list.add("1");
list.add(null);
}
}
listは境界のないワイルドカードを定義し、未知のタイプのlにタイプStringのデータを加えると、コンパイラはエラーを報告しますが、nullを加えるとエラーは報告されません.
1.サブクラス限定ワイルドカード:
extends E>
public class Test4 {
public static void c(List<? extends String> l) {
String s = l.get(0);
System.out.println(s);
//l.add("ceshi");
}
public static void main(String[] args) {
List<Integer> l1 = new ArrayList<Integer>();
l1.add(1);
List<String> l2 = new ArrayList<String>();
l2.add("2");
//error:The method c(List extends String>) in the type TestT is not applicable for the arguments (List)
//Test4.c(l1);
Test4.c(l2);
}
}
2.スーパークラス限定ワイルドカード:
super E>
は、指定されたクラスとその親タイプのデータを受け入れることができることを示します.>EまたはEの親でなければなりません.public class Test5 {
public static void superD(List<? super Integer> s) {
Object object = s.get(0);
System.out.println(object);
//s.add(10);
}
public static void main(String[] args) {
List<String> lString = new ArrayList<String>();
lString.add("2");
List<Object> lObject = new ArrayList<Object>();
lObject.add("2");
//error:The method superD(List super Integer>) in the type TestT is not applicable for the arguments (List)
//Test5.superD(lString);
Test5.superD(lObject);
}
}
3.PECS原則PECS全文は「Producer Extends,Consumer Super」であり、生産者としてextends、消費者としてsuperを使用することを意味する.
public static void main(String[] args) {
List<? extends Integer> fe = new ArrayList<Integer>();
//The method add(capture#5-of ? extends Object) in the type List is not applicable for the arguments (String)
//
fe.add(1);
List<? super Integer> fs = new ArrayList<Integer>();
fs.add(1);
//
for (Integer s : fe) {
}
for (Integer s : fs) {
}
}
}
わかるよadd()生産者の動作として集合にStringタイプのデータを追加すると、コンパイラはjavaに不確定なタイプが集合に加わることが許されないため、>Integerのサブクラスとして、このときコンパイラはfeがaddに入れられる具体的なサブタイプを知らない.そのため、エラーが報告されます(子クラスは親とは異なる形態を持っている可能性があるので、ルールを限定せずに、勝手にいろいろな子クラスを追加すると、リストの内容を読み取るときにエラーが発生します.Javaはいっそルールを前に限定しているからです).消費者の操作を行う場合、fsはデータを巡回する際、データ型>IntegerまたはIntegerの親であるため、>は具体的にどのタイプなのか分からないため、コンパイラがエラーを報告する.PECSの最大の原则は生产操作でも消费操作でも、コンパイラに具体的な操作のタイプが何なのかを知らせなければならないので、そうしないと耻ずかしくて、あげません!!
上記の例からルールを整理することができます.
T , , ? extends ;(Producer Extends)
T , , ? super ;(Consumer Super)
,