內部有一個方法用來傳入一個陣列並且把該陣列的資訊名稱印出來。
class ListName{
public static <T> void runList(List<? super T> list){
list.stream().forEach(x-> System.out.println(x.toString()));
}
}
現在有一個類別使用了這個方法class Obj<T>{
public void run(List<? super T> list){
ListName.runList(list);
}
}
class A extends ListName{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
class B extends ListName{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
你會發現只要這樣呼叫, 他都可以正確找到對應的類別資訊
A a1 = new A();
a1.setName("a1");
A a2 = new A();
a2.setName("a2");
B b1 = new B();
b1.setName("b1");
B b2 = new B();
b2.setName("b2");
List<ListName> list = new ArrayList<>();
list.add(a1);
list.add(a2);
list.add(b1);
list.add(b2);
Obj<A> o1 = new Obj<>();
o1.run(list);
結果如下a1
a2
b1
b2
< ? super T>的定義就是從該型態到它最初的T類別, 都會視為同一種型態。 白話一點就是如果你是某家族, 就可以使用。
< ? extends T>的定義就是只能限定繼承T類別以下的型態。
白話一點就是你必須是某人或它兒子才可以使用。
所以當你把下面程式碼改成extends就會發現編譯不了
class Obj<T>{
public void run(List<? extends T> list){
ListName.runList(list);
}
}
//...
Obj<A> o1 = new Obj<>();
o1.run(list);//無法編譯
原因就出在Obj只是允許T的型態, 也就是說 當你宣告T為A型態的時候,
所以run方法只允許A類別或A的子類別存取。