Java 泛型通配符 ? extends super 的用法 示例 1 : ? extends ArrayList heroList 表示這是一個Hero泛型或者其子類泛型 heroList 的泛型可能是Hero heroList 的泛型可能是APHero heroList 的泛型可能是ADHero ...
Java 泛型通配符 ? extends super 的用法
示例 1 : ? extends
ArrayList heroList<? extends Hero> 表示這是一個Hero泛型或者其子類泛型
heroList 的泛型可能是Hero
heroList 的泛型可能是APHero
heroList 的泛型可能是ADHero
所以 可以確鑿的是,從heroList取出來的對象,一定是可以轉型成Hero的
但是,不能往裡面放東西,因為
放APHero就不滿足
放ADHero又不滿足
package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void main(String[] args) {
ArrayList<APHero> apHeroList = new ArrayList<APHero>();
apHeroList.add(new APHero());
ArrayList<? extends Hero> heroList = apHeroList;
//? extends Hero 表示這是一個Hero泛型的子類泛型
//heroList 的泛型可以是Hero
//heroList 的泛型可以使APHero
//heroList 的泛型可以使ADHero
//可以確鑿的是,從heroList取出來的對象,一定是可以轉型成Hero的
Hero h= heroList.get(0);
//但是,不能往裡面放東西
heroList.add(new ADHero()); //編譯錯誤,因為heroList的泛型 有可能是APHero
}
}
示例 2 : ? super
ArrayList heroList<? super Hero> 表示這是一個Hero泛型或者其父類泛型
heroList的泛型可能是Hero
heroList的泛型可能是Object
可以往裡面插入Hero以及Hero的子類
但是取出來有風險,因為不確定取出來是Hero還是Object
package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void main(String[] args) {
ArrayList<? super Hero> heroList = new ArrayList<Object>();
//? super Hero 表示 heroList的泛型是Hero或者其父類泛型
//heroList 的泛型可以是Hero
//heroList 的泛型可以是Object
//所以就可以插入Hero
heroList.add(new Hero());
//也可以插入Hero的子類
heroList.add(new APHero());
heroList.add(new ADHero());
//但是,不能從裡面取數據出來,因為其泛型可能是Object,而Object是強轉Hero會失敗
Hero h= heroList.get(0);
}
}
示例 3 : 泛型通配符?
泛型通配符? 代表任意泛型
既然?代表任意泛型,那麼換句話說,這個容器什麼泛型都有可能
所以只能以Object的形式取出來
並且不能往裡面放對象,因為不知道到底是一個什麼泛型的容器
package generic;
import java.util.ArrayList;
import property.Item;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void main(String[] args) {
ArrayList<APHero> apHeroList = new ArrayList<APHero>();
//?泛型通配符,表示任意泛型
ArrayList<?> generalList = apHeroList;
//?的缺陷1: 既然?代表任意泛型,那麼換句話說,你就不知道這個容器裡面是什麼類型
//所以只能以Object的形式取出來
Object o = generalList.get(0);
//?的缺陷2: 既然?代表任意泛型,那麼既有可能是Hero,也有可能是Item
//所以,放哪種對象進去,都有風險,結果就什麼什麼類型的對象,都不能放進去
generalList.add(new Item()); //編譯錯誤 因為?代表任意泛型,很有可能不是Item
generalList.add(new Hero()); //編譯錯誤 因為?代表任意泛型,很有可能不是Hero
generalList.add(new APHero()); //編譯錯誤 因為?代表任意泛型,很有可能不是APHero
}
}
示例 4 : 總結
如果希望只取出,不插入,就使用? extends Hero
如果希望只插入,不取出,就使用? super Hero
如果希望,又能插入,又能取出,就不要用通配符?
練習: extends
如代碼所示,為了遍歷不同泛型的3種集合,需要設計3個方法
藉助? extends, 把代碼減肥到只是用一種方法
package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void iterate(ArrayList<Hero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void iterateAP(ArrayList<APHero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void iterateAD(ArrayList<ADHero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void main(String[] args) {
ArrayList<Hero> hs = new ArrayList<>();
ArrayList<APHero> aphs = new ArrayList<>();
ArrayList<ADHero> adhs = new ArrayList<>();
iterate(hs);
iterateAP(aphs);
iterateAD(adhs);
}
}
答案:
使用一個方法:
public static void iterate(ArrayList<? extends Hero> list) {
}
就表示傳遞進去的集合的泛型可以是Hero的子類
package generic;
import java.util.ArrayList;
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
public class TestGeneric {
public static void iterate(ArrayList<? extends Hero> list) {
for (Hero hero : list) {
System.out.println(hero.name);
}
}
public static void main(String[] args) {
ArrayList<Hero> hs = new ArrayList<>();
ArrayList<APHero> aphs = new ArrayList<>();
ArrayList<ADHero> adhs = new ArrayList<>();
iterate(hs);
iterate(aphs);
iterate(adhs);
}
}