你要做一個不動聲色的大人了,不準情緒化,不準偷偷想念,不準回頭看,去過自己另外的生活,你要聽話,不是所有的魚都會生活在同一片海里, ——村上春樹 《舞!舞!舞!》
Q:什么是泛型?

-
Java泛型本質:引數化型別
從字面意思就可以看出,就是把“型別變成了引數”,如String型別、Integer型別等都作為引數,
==============================================================================
-
泛型-承擔“保安”的角色

-
Q:泛型如何使用?
1.List mylist1=new ArrayList();//未使用泛型;
2.List<String> mylist2=new ArrayList<String>();//引數化型別;
- 集合類容納的物件都是Object類的實體,也就是說字串或整型資料等都能存入List串列中,因為Object類是所有類的父類,
=============================================================================
下面看看未使用泛型和使用了泛型的區別:
- 未使用泛型:

-
字串資料、整型資料等都能存入List串列中,List串列把這些資料都看作時Object型別,當我們只想取出某種型別
資料時,需要進行強制轉換,如上圖,字串強轉字串這個沒啥問題,但是整型強轉字串型別就會運行報錯,出現
ClassCastException錯誤(型別不匹配),
=============================================================================
- 使用泛型:

如上述代碼,
如果不是就會被攔截(報錯),把String作為引數,型別引數化,這就是泛型,當然你可以把其他型別作為引數,
=============================================================================
Q:泛型有什么作用?

型別引數——型別實參與型別形參
-
型別引數可以類比Java方法中的形參和實參,型別實參就如我前面舉的例子,那型別形參長什么樣呢?
-
看下圖:API檔案中List介面的定義

-
這很顯然使用了泛型,但它不是確定的資料型別,這就是型別形參,泛型中使用大寫的英文字母來作為型別形參,
-
這里的E是一個型別形參,實際中你可以寫成String、Integer等等,
=============================================================================
菱形運算子
List<String> mylist2=new ArrayList<String>();
-
上述代碼中,mylist2是List
型別的,顯然創建的物件也必須是List 型別的,任何其他型別的引數都會產生編譯錯誤, Java7增加了一種新的語言特性,稱為菱形運算子,上面代碼可改寫為:
List<String> mylist2=new ArrayList<>();
泛型通配符
- 無界通配符
- 上界通配符
- 下界通配符
1.代碼示例:PrintList方法列印任何型別的串列
public static void PrintList(List<Object> list) {
for (Object o: list)//增強型for回圈列印串列
System.out.println(o + " ");
}
//The method PrintList(List<Object>) in the type PrintList is not applicable for the arguments (List<Integer>)
//不能列印List<Integer>, List<String>等等,因為它們不是List<Object>的子型別(只存盤整型的串列不是可存盤任何型別的串列的子類),
//使用通配符(?):表示未知型別,即可以是String型別,也可以是Integer型別等等,
public static void PrintList(List<?> list){}
2/3.代碼示例:
class Food {}//食物類
class Fruit extends Food {}//水果類
class Apple extends Fruit {}//蘋果類
public class Plate<T> {//盤子類(泛型類)
public Plate(T t){item=t;}
public void set(T t){item=t;}//放和取操作
public T get(){return item;}
private T item;
public static void main(String[] args) {
//定義水果盤子
Plate<Fruit> p1=new Plate<Apple>(new Apple());//Error ??與水果有繼承關系,但??盤子與水果盤子之間沒繼承關系
//<? extends T>上界通配符,中間表示T及任何T的派生類的型別資料,這個例子中理解為‘這個盤子能裝任何水果’,蘋果當然沒問題
//能裝任何水果的盤子與蘋果盤子之間就有了繼承關系(Plate<? extends Fruit> 是Plate<Apple>的基類)
Plate<? extends Fruit> p1=new Plate<Apple>(new Apple());
//<? extends T>不能往里存,只能往外取,是水果就能放進來,但編譯器并不知道是什么水果,當要對蘋果賦值時,編譯器找不到,
p1.set(new Fruit()); //Error
//讀取出來的東西只能存放在Fruit或它的基類里,從水果盤子里來的肯定是水果,或者是食物(基類)
Fruit newFruit1=p1.get();
Object newFruit2=p1.get();
Apple newFruit3=p1.get(); //Error
//<? super Fruit>下界通配符,表示T及任何T的基類的型別資料,這個例子中理解為‘這個盤子能裝任何食物(水果基類)’,
Plate<? super Fruit> p2=new Plate<Fruit>(new Fruit());
//<? super T>不影響往里存,但往外取只能放在Object物件里
p2.set(new Fruit());
p2.set(new Apple());
Apple newFruit4=p2.get(); //Error
Fruit newFruit5=p2.get(); //Error
Object newFruit6=p2.get();
}
}
上界下界參考> https://blog.csdn.net/hello_worldee/article/details/77934244
簡單泛型類和介面
public class GenericMemoryCell <E> {//泛型類
public E read()
{return Value;}
public void write(E x)
{Value=https://www.cnblogs.com/wuzh/p/x;}
private E Value;
}
package java.lang
//泛型介面,Comparable介面;
public interface Comparable<E>
{
public int compareTo(E other)
}
注:參考百度百科及《資料結構與演算法分析》
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/254669.html
標籤:Java
