JAVA泛型相關知識學習

一     泛型(Generic)

一、概述

1、JDK1.5版本以後出現的新特性。用於解決安全問題,是一個類型安全機制。

2、JDK1.5的集合類希望在定義集合時,明確表明你要向集合中裝入那種類型的數據,無法加入指定類型以外的數據。

3、泛型是提供給javac編譯器使用的可以限定集合中的輸入類型說明的集合時,會去掉“類型”信息,使程序運行效率不受影響,對參數化的泛型類型,getClass()方法的返回值和原始類型完全一樣。

4、由於編譯生成的字節碼會去掉泛型的類型信息,只要能跳過編譯器,就可以往某個泛型集合中加入其它類型的數據,如用反射得到集合,再調用add方法即可。

5、沒有使用泛型時,只要是對象,不管是什麼類型的對象,都可以存儲進同一個集合中。使用泛型集合,可以將一個集合中的元素限定爲一個特定類型,集合中只能存儲同一個類型的對象,這樣更安全;並且當從集合獲取一個對象時,編譯器也可以知道這個對象的類型,不需要對對象進行強制類型轉換,這樣更方便。

6、格式:

       通過<>來定義要操作的引用數據類型

      如:ArrayList<String>  //定義要存入集合中的元素指定爲String類型

7、好處

       a、將運行時期出現的問題ClassCastException,轉移到了編譯時期。方便於程序員解決問題。讓運行時期問題減少、安全。

       b、避免了強制轉換的麻煩。如在實現某一個接口時,指定傳入接口方法的實參的類型的話,在複寫該接口方法時就可以直接使用指定類型,而不需要強制轉換。

泛型研究:

      只有類被定義成了泛型,纔可以對其進行參數化應用。

二、泛型定義中的術語:

        如:ArrayList<E>類和ArrayList<Integer>

        1、ArrayList<E>整個稱爲泛型類型

        2、ArrayList<E>中的E稱爲類型變量或類型參數

        3、整個ArrayList<Integer>稱爲參數化類型

        4、ArrayList<Integer>中的Integer稱爲類型參數的實例或實際類型參數

        5、ArrayList<Integer>中的<>稱爲typeof

        6、ArrayList稱爲原始類型

       參數化:parametered,已經將參數變爲實際類型的狀態。

三、在使用java提供的對象時,什麼時候寫泛型?

        通常在集合框架中很常見,只要見到<>就要定義泛型。

        其實<>就是用來接收類型的。當使用集合時,將集合中要存儲的數據類型作爲參數傳遞到<>中即可。

四、關於參數化類型的幾點說明:

1、參數化類型與原始類型的兼容性

        第一、參數化類型可引用一個原始類型的對象,編譯只是報警告。

        如:Collection<String>coll = new Vector();

        第二、原始類型可引用一個參數化類型的對象,編譯報告警告

        如:Collectioncoll = new Vector<String>();

        原來的方法接受一個集合參數,新類型也要能傳進去。

2、參數的類型不考慮類型參數的繼承關係:

        Vector<String> v = newVector<Objec>();//錯誤的

        不寫Object沒錯,寫了就是明知故犯

        Vector<Objec> v = newVector<String>();//錯誤的

3、編譯器不允許創建泛型變量的數組。即在創建數組實例時,數組的元素不能使用參數化的類型

        如:Vector<Integer>vectorList[] = new Vector<Integer>[10];//錯誤的

五、泛型類

1、若類實例對象中要使用到同一泛型參數,即這些地方引用類型要保持同一個實際類型時,這時候就要採用泛型類型的方式進行定義,也就是類級別的泛型。

2、什麼時候定義泛型類

       當類中要操作的引用數據類型不確定的時候,早期定義Object來完成擴展。現在定義泛型來完成擴展。

3、泛型類定義的泛型,在整個類中有效。如果被方法使用,那麼泛型類的對象明確要操作的具體類型後,所以要操作的類型就已經固定了。

4、類級別的泛型是根據引用該類名時指定的類型信息來參數化類型變量的,例如,如下兩種方式都可以:

        GenericDao<String>dao = null;

        newgenericDao<String>();

5、語法格式:

       class Utils<XX>

        {

             private XX s;

             public void setxx(XX s)

             {

                 this.s=s;

             }

             public XX getXX()

             {

                  return s;

             }

        }

注意:

        1、在對泛型進行參數化時,類型參數的實例必須是引用類型,不能是基本類型。

        2、當一個變量被聲明爲參數時,只能被實例變量和方法調用(還有內嵌類型),而不能被靜態變量和靜態方法調用,因爲靜態成員是被所有參數化的類共享的,所以靜態成員不應該有類級別的類型參數。

六、泛型方法

        爲了讓不同方法可以操作不同類型,而且類型還不確定。那麼可以將泛型定義在方法上。

特殊之處:

        靜態方法不可以訪問類上定義的泛型。如果靜態方法操作的應用數據類型不確定,可以將泛型定義在方法上。

泛型方法的特點:

         1、位置:用於放置泛型的類型參數的<>應出現在方法的其他所有修飾符之後和在方法的返回類型之前,也就是緊鄰返回值之前,按照慣例,類型參數通常用單個大寫字母表示。

         2、只有引用類型才能作爲泛型方法的實際參數。

         3、除了在應用泛型時可以使用extends限定符,在定義泛型時也可以使用extends限定符。例如,Class.getAnnotation()方法的定義。並且可以用&來指定多個邊界,如<V extends Serializable& cloneable> void method(){}。 

         4、普通方法、構造函數和靜態方法中都可以使用泛型。

         5、可以用類型變量表示異常,稱之爲參數化的異常,可用於方法的throws列表中,但是不能用於catch子句中。

         6、在泛型中可同時有多個類型參數,在定義它們的<>中用逗號分開。例如:

               public static <K,V> V getValue(K key) { return map.get(key);}

       通配符方案要比泛型方法更有效,當一個類型變量用來表達兩個參數之間或參數和返回值之間的關係時,即同一個類型變量在方法簽名的兩處被使用,或者類型變量在方法體代碼中也被使用,而不是僅在簽名的時候使用,才需要使用泛型方法。

小結:

對泛型的定義:

        第一、定義泛型:當又不確定的類型需要傳入到集合中,需要定義泛型。

        第二、定義泛型類:如果類型確定後,所操作的方法都是屬於此類型,則定義泛型類。

        第三、定義泛型方法:如果定義的方法確定了,裏面所操作的類型不確定,則定義泛型方法。

 

二     System類

一、概述

1、System是描述系統一些信息的類,類中的屬性和方法都是靜態的。不能被實例化,沒有提供構造函數。

2、兩個部分:

       out:標準輸出流。默認是控制檯。

        in:標準輸入流。默認是鍵盤。

二、方法

1、獲取系統的屬性信息:

        PropertiesgetProperties();

說明:

        1)此方法返回的雙列集合,即鍵值對;因爲Properties是Hahstable的子類,也就是Map集合的一個子類對象,那麼通過Map方法取出該集合中的元素。

         2)該集合存儲的都是字符串,沒有泛型定義

2、獲取指定屬性信息:

        String getProperty(Stringkey);

3、在系統內定義特有信息:

        String setProperty(Stringkey,String value);

4、如何在jvm啓動時,加載一些屬性信息:

       通過命令:java -D<name>=<value>可以設置特有的系統屬性信息

 

三     Runtime類

一、概述

        1、每個java應用程序都有一個Runtime類實例,使用應用程序能與其中運行的環境相連接,應用程序不能創建自己的Runtime類的實例,是由系統底層自己創建的。

        2、該類中並沒有提供構造函數。說明不可以new對象。那麼會直接想到該類中的方法都是靜態的。查閱API文檔發現,該類中還有非靜態方法。說明該類肯定會提供了方法獲取本來對象。而且該方法是靜態的,並返回值類型是本來類型。

        3、由以上特點可以看出該類使用了單例設計模式完成。

二、方法

1、獲取本類對象

        static RuntimegetRuntime();

2、在單獨的進程中執行指定字符串命令

        Processexec(String command);

3、在Process中有一個殺掉子進程的方法,可將exec方法開啓的進程結束

        void destroy();

 

四     時間類

一、Date類

1、概述

        Date類表示特定的瞬間,精確到毫秒。

        java中的默認顯示格式爲:Mon Jun 10 22:35:21 CST2013

2、自定義格式

        默認的格式不一定滿足每個人的需求,那麼就需要自定義格式化模式。因爲Date類中的大部分方法已過時,所以只能找其子類來實現。子類DateFormat中有format方法可以實現,但是DateFormat是抽象類,不能實例化。但是其下有個SimpleDateFormat子類,可以定義時間模式。

具體步驟:

        1)創建Date對象

        2)將時間模式封裝到SimpleDateFormat對象中

        3)調用format方法讓格式化模式指定Date對象
二、Carendar類

1、概述:

        1)Calendar是一個抽象類,它爲特定瞬間與一組諸如YEAR、MONTH、DAY_OF_MONTH等日曆字段之間的轉換提供了一些方法。

        2)Calendar可以對年月日等時間進行獲取。並提供了相應的子段值。可參閱API文檔。

2、方法:

2.1、基本獲取時間

        1)獲取年份:Calendar.YEAR

        2)獲取月份:Calendar.MONTH

        3)獲取日期:Calendar.DAY_OF_MONTH

        4)獲取星期:Calendar.DAY_OF_WEEK

        5)獲取小時:Calendar.HOUR_OF_DAY

        6)獲取分鐘:Calendar.MINUTE

        7)獲取秒數:Calendar.SECOND

2.2、設置時間:

        1)根據日曆的規則,爲給定的日曆字段添加或減去指定的時間量:

                void add(int field,int amount);

        2)獲取指定的日曆字段對應的時間值:

                int get(int field);

        3)將給定日曆字段對應的時間值設置爲給定值:

                void set(int field,int value);

       設置日曆字段 YEAR、MONTH和DAY_OF_MONTH的值:

                void set(int year,int month,int date);

 

五     Math類

一、概述

        Math 類包含用於執行基本數學運算的方法,如初等指數、對數、平方根和三角函數。該類全爲靜態方法。

二、方法

        1、doubleceil(double d);//返回大於指定數據的最小整數

        2、doublefloor(double d);//返回小於指定數據的最大整數

        3、double pow(doublea,double b);//返回a的b次方

        4、long round(doubleb);//返回b四捨五入的值 

        5、doublerandom();//返回正號的double值,是一個大於等於0.0且小於1.0的隨機數

三、Random類

        這是java.util中的一個單獨的類,該類對象用於獲取隨機數。與Math中的random方法是一樣的,不過這個類有自身的方法,可以將相應的隨機數強轉爲指定基本數據類型。

        如:intnextInt(int n);//返回一個僞隨機數,它是取自此隨機數生成器序列的、在 0(包括)和指定值(不包括)之間均勻分佈的 int值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章