什么是泛型?為什么使用泛型?


今天看了幾篇文章深有體會,可以說把以前工作中一些情況串起來了

泛型:就是一種不確定的數據類型。
// 比如:ArrayList<E> E就是泛型。 這種不確定的數據類型需要在使用這個類的時候才能夠確定出來。
// 泛型可以省略,如果省略,默認泛型是Object類型。
// 泛型的好處:
// 1. 省略了強轉的代碼。
// 2. 可以把運行時的問題提前到編譯時期。

為什么要使用泛型?

為了了解這個問題,我們先看下面的代碼,代碼省略了一些內容,但功能是實現一個棧,這個棧只能處理int數據類型:

public class Stack

{

     private int[] m_item;

     public int pop(){...}

     public void Push(int item){...}

     public Stack(int i)

     {

          this.m_item = new int[i];

     }

}

上面的代碼運行得很好,但是,當我們需要一個棧來保存String類型時,該怎么辦呢?很多人就想到把上面的代碼復制一份,把int改成String不就行了。當然,這樣做本身是沒有任何問題的,但一個優秀的程序員是不會這樣做的,因為他想到若以后再需要long、Node類型的棧該怎么做呢?還要再復制嗎?優秀的程序員會想到用一個通用的數據類型Object來實現這個棧:

 

public class Stack

 

    {

        private object[] m_item;

        public object Pop(){...}

        public void Push(object item){...}

        public Stack(int i)

        {

            this.m_item = new[i];

        }

      }

這個棧寫得不錯,它非常靈活,可以接收任何數據類型,可以說是一勞永逸。但全面地講,也不是沒有缺陷的,主要表現在:

當Stack處理值類型時,會出現裝箱、拆箱操作,但將用到的數據類型的強制轉換操作,增加處理器的負擔。

在數據類型的強制轉換上還有更嚴重的問題(假設stack是Stack的一個實例):
Node1 x = new Node1();

            stack.Push(x);

         Node2 y = (Node2)stack.Pop();

上面的代碼在編譯時是完全沒問題的,但由於Push了一個Node1類型的數據,但在Pop時卻要求轉換為Node2類型,這將出現程序運行時的類型轉換異常,但卻逃離了編譯器的檢查。

 

針對object類型棧的問題,我們引入泛型,他可以優雅地解決這些問題。泛型用用一個通過的數據類型T來代替object,在類實例化時指定T的類型,運行時(Runtime)自動編譯為本地代碼,運行效率和代碼質量都有很大提高,並且保證數據類型安全。

 

使用泛型
下面是用泛型來重寫上面的棧,用一個通用的數據類型T來作為一個占位符,等待在實例化時用一個實際的類型來代替。讓我們來看看泛型的威力:

public class Stack<T>

{

    private T[] m_item;

    public T Pop(){...}

    public void Push(T item){...}

    public Stack(int i){

         this.m_item = new T[i];

    }

}

類的寫法不變,只是引入了通用數據類型T就可以適用於任何數據類型,並且類型安全的。這個類的調用方法:

//實例化只能保存int類型的類

Stack<int> a = new Stack<int>(100);

   a.Push(10);

   a.Push("8888");//這行編譯不通過,因為類a只接收int類型的數據

   int x = a.Pop();

Stack<String> b = new Stack<String>(100);

    b.Push(10);//這行編譯不通過,因為類b只接收String類型的數據

   String y = b.Pop();

 

這個類和Object實現的類有截然不同的區別:

1.它是類型安全的。實例化了int類型的棧,就不能處理String類型的數據,其他的數據類型也一樣。

2.無需裝箱和拆箱。這個類在實例化時,按照所傳入的數據類型生成本地代碼,本地代碼數據類型已確定,所以無需裝箱和拆箱。

3.無需類型轉換。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM