Java語言基礎:泛型

來源:互聯網
上載者:User

     我必須承認我不是一個Java程式員,日常開發主要是C++和Delphi,使用Java完全是為了開發Android應用。今天在看Java的泛型,有些方面感到很奇怪,先來看下面的代碼:

 

    class Shape {
        public void Draw()
{
            System.out.println("Draw Shape");
        }
   
}

 

    class Rect extends Shape
{    
        @Override
        public void Draw()
{
            System.out.println("Draw Rect");
        }
   
}

 

    class Line extends Shape
{
        @Override
        public void Draw()
{
            System.out.println("Draw Line");
        }
   
}

 

    class Drawer<T> {
        public
void DrawShape(T shape) {
            shape.Draw();
        }
   
}

 

   
Drawer是一個泛型類,DrawShape方法繪製一個圖形,從使用C++模板的經驗來看,這絕對是正確的,但Java居然出現編譯錯誤了:shape.Draw這樣調用不被允許。
   
我再把代碼修改了一下: 

    class Drawer<T> {
        public
void DrawShape(T shape) {
            shape.toString();
        }
   

    這樣就編譯通過了,看來Java是把 T 解釋成 Object
了,有沒有辦法讓它解釋成Shape呢,又看了一下文檔,才知道要這樣寫: 

    class Drawer<T extends Shape>
{
        public void DrawShape(T shape)
{
            shape.Draw();
        }
    }     原來類型參加也可以指定繼承的,如果是這樣,那和不用泛型的代碼有什麼區別呢:    class Drawer {
        public void
DrawShape(Shape shape) {
            shape.Draw();
        }
   
}

   
看來Java的泛型和C++的模板有很大的區別,Java的泛型更多的是用於容器,並且在我看來,它的最大作用是省去類型轉換的操作,並且在編譯期檢查一下類型是否正確,傳統容器類可能要這樣寫: 

     List intList = new ArrayList(); 
    
intList.add(new Integer(10));
     Integer i =
(Integer)intList.get(0); 

有了泛型以後可以改成這樣寫: 

     List<Integer> intList = new
ArrayList<Integer>(); 
     intList.add(new Integer(10));
    
Integer i = intList.get(0);  

   
我還注意到泛型參數不能是基本類型,只能是對象,這跟C++的模板差距又進一步拉大了。感覺Java泛型的作用並不是很大,但又搞得很複雜,比如萬用字元這種東西,先看下面的代碼: 

    private static void
PrintList(List<Object> list) {
        for (Object o: list)
{
            System.out.println(o.toString());
        }
    }

 

    public static void DoTest() {
        
List<Rect> intList = new ArrayList<Rect>(); 
        
intList.add(new Rect());
         intList.add(new Rect());
        
intList.add(new Rect());
         PrintList(intList);
    } 

   
PrintList這一句編譯不過,因為List<Rect>與List<Object>不相容,怎麼改呢,用萬用字元: 

    private static void PrintList(List<?>
list) {
        for (Object o: list)
{
            System.out.println(o.toString());
        }
    } 

    List<?>
的意思是列表的元素類型未知,但變成Object總是沒有問題的,所以可以編譯通過,現在如果我想它是Shape,該怎麼辦呢,用萬用字元再加Extends的辦法: 

    class Shape {
        public String
getName() {
            return "Shape";
        }
    }

 

    class Rect extends Shape
{    
        @Override
        public String getName()
{
            return "Rect";
        }
    }

 

    public class TestGenerics {

 

        private static void PrintList(List<?
extends Shape> list) {
            for (Shape s: list)
{
                System.out.println(s.getName());
            }
        }

 

        public static void DoTest()
{
             List<Rect> intList = new
ArrayList<Rect>(); 
             intList.add(new
Rect());
             intList.add(new Rect());
            
intList.add(new Rect());
             PrintList(intList);
        }
   

    看看List<? extends Shape>
list,我已經快被搞暈了,它的意思是List的項必須是Shape或繼承自Shape,搞了一圈又回到使用多態就可以解決問題了。
   
但這個用法又帶來了一些限制,就是List<? extends Shape> list中的list是不能增加刪除元素的,比如:  

    private static void PrintList(List<?
extends Shape> list) {
        for (Shape s: list)
{
            System.out.println(s.getName());
        }
        list.add(new
Line());
    } 

    list.add(new Line())這句編不過,因為帶有萬用字元的集合類,根本不能確定它的元素是什麼類型。
   
個人覺得Java不要泛型的好,因為沒有一定要用它的理由啊,它只可以幫你自動轉換和檢查一下類型,但它所帶來的文法複雜性,其實是得不償失的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.