天天看點

Java泛型集合的了解

 <b>什麼是泛型?</b>

泛型(Generic type 或者 generics)是對 Java 語言的類型系統的一種擴充,<b>以支援建立可以按類型進行參數化的類</b>。可以把類型參數看作是使用參數化類型時指定的類型的一個占位符,就像方法的形式參數是運作時傳遞的值的占位符一樣。

Map 類允許您向一個 Map 添加任意類的對象,即使最常見的情況是在給定映射(map)中儲存某個特定類型(比如 String)的對象。

因為 Map.get() 被定義為傳回 Object,是以一般必須将 Map.get() 的結果強制類型轉換為期望的類型,如下面的代碼所示:

Map m = new HashMap(); 

m.put("key", "value"); 

String result = (String)m.get("key"); 

想讓程式編譯通過,必須将m.get(“key”)強制轉換為String類型,因為這裡放入了String類型的值,取得的結果也一定是String類型的。如果你往map裡放入了不是String類型的值,那麼将會報ClassCastException錯誤。

理想情況下,您可能會得出這樣一個觀點,即 m 是一個 Map,它将 String 鍵映射到 String 值。這可以讓您消除代碼中的強制類型轉換,<b>同時獲得一個附加的類型檢查層,該檢查層可以防止有人将錯誤類型的鍵或值儲存在集合中</b>。這就是泛型所做的工作。

<b>泛型帶來的好處</b><b></b>

<b></b>

<b>類型安全</b><b></b>

限制了變量定義的類型。

<b>消除強制類型轉換</b>

還是拿剛才的例子說

Map&lt;String, String&gt; m = new HashMap&lt;String, String&gt;(); 

String result = m.get("key"); 

上面的代碼是不是少了強制轉換而且代碼看着也簡潔多了,這就是泛型的好處之一。平時大家寫的時候,編輯器會有個黃色的感歎号來提醒你需要使用泛型。

<b>泛型的通配符</b><b></b>

<b>?通配符</b>

使用?通配符可以引用其他各種參數化的類型,?通配符定義的變量主要用作引用,可以調用與參數化無關的方法,不能調用與參數化有關的方法。

下面看個例子:

public class People { 

    private String name; 

    private String job; 

    public People() { 

    } 

    public People(String _name, String _job, int _sex) { 

        this.name = _name; 

        this.job = _job; 

        this.sex = _sex; 

    public void SayHello() { 

        System.out.println("我是一位" + job + ";我的名字叫" + name); 

    public String getName() { 

        return name; 

    public void setName(String name) { 

        this.name = name; 

    public String getJob() { 

        return job; 

    public void setJob(String job) { 

        this.job = job; 

    public int getSex() { 

        return sex; 

    public void setSex(int sex) { 

        this.sex = sex; 

    private int sex; 

public class SoftwareEngineer extends People{ 

    public void coding(){ 

        System.out.println("coding……"); 

public class Cook extends People { 

    public void cook(){ 

        System.out.println("cooking……"); 

主方法:

List&lt;? super People&gt; flist = new ArrayList&lt;People&gt;(); 

        flist.add(new People());

        SoftwareEngineer soft = (SoftwareEngineer) flist.get(0); 

        soft.coding(); 

輸出結果:coding……

注意這裡是super,那麼flist.add()裡面添加new People(),也可以添加new SoftwareEngineer()或者new Cook(),都可以!

那麼,我們換成下面的看看:

List&lt;? extends People&gt; flist = new ArrayList&lt;People&gt;(); 

這裡就不可以添加了。。。?

list中為什麼不能加入people類和people類的子類呢,原因是這樣的:  

List&lt;? extends People&gt;表示上限是People,下面這樣的指派都是合法的  

List&lt;? extends People&gt; list1 = new ArrayList&lt;People&gt;();   

List&lt;? extends People&gt; list2 = new ArrayList&lt;SoftWareEngineer&gt;();   

List&lt;? extends People&gt; list3 = new ArrayList&lt;Cook&gt;();  

如果List&lt;? extends People&gt;支援add方法的方法合法的話:

   list1可以add People和所有People的子類  

   list2可以add SoftWareEngineer和所有SoftWareEngineer的子類  

   list3可以add Cook和所有Cook的子類  

這樣的話,問題就出現了  

   List&lt;? extends People&gt;所應該持有的對象是People的子類,而且具體是哪一個子類還是個未知數,是以加入任何People的子類都會有問題,因為如果add People的話,可能List&lt;? extends People&gt;持有的對象是new ArrayList&lt;Cook&gt;() SoftWareEngineer的加入肯定是不行的,如果 如果add Cook的話,可能List&lt;? extends People&gt;持有的對象是new ArrayList&lt;Cook的子類&gt;()  

   SoftWareEngineer的加入又不合法,是以List&lt;? extends People&gt; list 不能進行add,而List&lt;? super People&gt; list 表示list持有的對象是People的父類,下限是 People,是以list中add People或People的子類是沒有問題的。

本文轉自shyy8712872 51CTO部落格,原文連結:http://blog.51cto.com/shuyangyang/1030760,如需轉載請自行聯系原作者