知識點:html
泛型的概念數組
泛型類,泛型接口,泛型方法測試
通配符ui
? extend A:能夠引用A以及子類,只能夠存放null
? super A:能夠引用A以及父類,能夠存放A以及A的子類
參考博客:https://www.cnblogs.com/lwbqqyumidi/p/3837629.html
https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247485714&idx=1&sn=7839a7caf10399d59a6a46e9bc5668cd&chksm=97fb07dba08c8ecd5da21ae1f3cede4912f81672ef20d35d840d6a7889abb337c214ac7b9579&scene=0&xtrack=1&key=b2d158037147950fd504ba5526dd4c3f7dd6abf9bde19a33a1abf6e826e1f1c7600f6b07fd9d1905e8125e47c0984426c7ff9b894ff5ef3bf42a04574e4f4f3fe6bdb84178f4acfb2117122a61da2a21&ascene=14&uin=MjEzMzY3MzkzNA%3D%3D&devicetype=Windows+10&version=62060739&lang=zh_CN&pass_ticket=1kSdouT4BHYceycY9n%2FLFiQUOaQQc%2FwAunx2nhzC7rjp%2FsScflTyHbyH3JczQ6hL&winzoom=1
一:什麼是泛型,爲何使用方式泛型this
(1)什麼是泛型spa
把一個集合中的內容限制爲一個特定的數據類型3d
(2)爲何使用泛型htm
先看一下一個例子:對象
public class genTest {
public static void main(String[] args) {
List list=new ArrayList();
list.add("AA");
list.add("BB");
list.add(12);
for (int i=0;i<list.size();i++){
String name=(String)list.get(i);//類型轉換
System.out.println(name);
}
}
}
上面程序會報類型轉化異常blog
緣由:上面的代碼中,咱們定義了一個list集合,分別向集合中加入String,Integer兩種類型的數據,這是list會默認都轉爲Object類型元素,在循環時,Integer類強轉成String類型的元素,會報錯類型轉換異常的錯誤,這種錯誤在編譯階段不會顯示,只有在運行階段纔會出現
上面再編譯階段不顯示錯誤,是由於list並不清楚本身的存的元素類型,在遍歷取出元素時,默認把元素編譯改爲Object的類型,可是運行時,時元素自己的類型,若是咱們讓集合一開始存數據時,就知道本身存的數據類型,那麼在編譯期間能夠避免這種錯誤,泛型就很好解決了這種問題
上面的程序能夠這樣改一下(加泛型List<String> list=new ArrayList<>();)
二:泛型類,泛型接口,泛型方法
泛型類,泛型接口是傳入一個不肯定的對象類型,根據實際傳入的不一樣對象,調用相同的方法(在接口,類後面加<E>其中E能夠隨便定義T,F等等)
泛型方法:方法參數中加入泛型,能夠傳入不一樣的類型的對象(在返回值前面加<T>)
//泛型類
public class Parent<E> {
private String name;
private E e;
public Parent(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public E getE() {
return e;
}
public void setE(E e) {
this.e = e;
}
//聲明泛型方法
public <T> T getT(T t){
return t;
}
//實現數組到集合的複製
public <T> List<T> fromArrayToList(T[] t, List<T> list){
for (T t1:t){
list.add(t1);
}
return list;
}
}
測試類
public class Children<E> extends Parent<E> {
@Test
public void Testgenericity1(){
//泛型類,泛型方法
Children c=new Children();
c.setE("AA");
System.out.println(c.getE());
c.setE(12);
System.out.println(c.getE());
//泛型方法
Boolean b1=(Boolean)(c.getT(true));
System.out.println(b1);
Double d1=(Double) (c.getT(11.1));
System.out.println(d1);
String[] strarr=new String []{"AA","BB","CC"};
List<String> list=new ArrayList<>();
List<String> list1=c.fromArrayToList(strarr,list);
System.out.println(list1);
Integer[] strarr1=new Integer[]{11,22,33};
List<Integer> list2=new ArrayList<>();
List<Integer> list3=c.fromArrayToList(strarr1,list2);
System.out.println(list3);
}
}
運行結果:

三:通配符 ?
(1)統配符的使用
@Test
public void Testgenericity3(){
//通配符的使用
List<String> list=new ArrayList<>();
list.add("AA");
list.add("BB");
List<?> slist=list;
//能夠讀取聲明爲統配符的集合對象(轉成Object)
Iterator<?> iterator=slist.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//不容許向申明爲通配符的集合類中寫入對象,可是null能夠
//slist.add("AA");
slist.add(null);
}
(2)泛型與繼承的關係
? extend A:能夠引用A以及子類,只能夠存放null
? super A:能夠引用A以及父類,能夠存放A以及A的子類
(1)? extend A:只能夠存放null ? super A:能夠存放A以及A的子類
Grandfather、Father、Son三者之間的繼承關係
public class Grandfather {
private String name;
private Integer age;
public Grandfather() {
}
}
class Father extends Grandfather {
public Father(){}
}
class Son extends Father {
public Son(){}
}
測試類:
@Test
public void Testgenericity4(){
List<? extends Father> list1=new ArrayList<>();//只能存放null
//list1.add(new Grandfather());//錯誤
//list1.add(new Father()); //錯誤
//list1.add(new Son()) //錯誤
list1.add(null);
System.out.println(list1);
List<? super Father> list2=new ArrayList();//能夠存放Father以及Father的子類
list2.add(new Father());
list2.add(new Son());
list2.add(null);
//list2.add(new Grandfather());//錯誤
System.out.println(list2);
}
運行結果:
(2)? extend A:能夠引用A以及子類 ? super A:能夠引用A以及父類 (引用後可以添加的元素仍是A以及A的子類)
測試類:
@Test
public void Testgenericity2(){
List<Grandfather> list1=new ArrayList<>();
List<Father> list2=new ArrayList<>();
//list1=list2; //若A是B的子類,List<A>,不是List<B>的子接口
List<?> list=null; //通配符 ?
list=list1;
List<? extends Father> list3=new ArrayList<>();
List<Son> list4=new ArrayList<>();
list3=list4;
list3=list2;
//list3=list1;//錯誤
List<? super Father> list5=new ArrayList();
list5=list1;
list5=list2;
//list5=list4;//錯誤
}
四:補充:
1.不能夠在static方法中使用泛型的聲明(類加載時,方法已加載,泛型沒法肯定,初始化對象時,能夠肯定)
2.不能夠在try-catch中使用類的泛型聲明