Java第三部分

第十章 異常處理

  • 1,異常概述

    • 在程序中,錯誤可能產生於程序員沒有預料到的各種情況,或者是超出了程序員可控範圍的環境因素,如用戶的壞數據、試圖打開一個根本不存在的文件等。

    • Java中這種在程序運行時可能出現的一些錯誤稱爲異常。異常是一個在執行期間發生的事件,它中斷了正在執行的程序的正常指令流。

    • 通過異常處理機制,可以將非正常情況下的處理代碼與程序的主邏輯分離,即在編寫代碼主流程的同時在其他地方處理異常。
      在Java中,如果某個方法拋出異常,既可以在當前方法中進行捕捉,然後處理該異常,也可以將異常向上拋出,由方法調用者來處理。

  • 2,捕捉異常

    • Java語言的異常捕獲結構由try、catch和finally 3部分組成。

    • try語句存放的是可能發生異常的Java語句;catch程序塊在try語句塊之後,用來激發被捕獲的異常;finally語句塊是異常處理結構的最後執行部分,無論try塊中的代碼如何退出,都將執行finally塊。

    • 當try代碼塊中的語句發生異常時,程序就會調轉到catch代碼塊中執行,執行完catch代碼塊中的程序代碼後,將繼續執行catch代碼塊後的其他代碼,而不會執行try代碼塊中發生異常語句後面的代碼。

    • Java的異常處理是結構化的,不會因爲一個異常影響整個程序的執行。

    • 通常,異常處理用以下三個函數來獲取異常的有關信息。

      • getMessage();輸出錯誤性質
      • toString();給出異常的類型與性質
      • printStackTrace();指出異常的類型、性質、棧層次及出現在程序中的位置。
  • 3,自定義異常

    • 使用Java內置的異常類可以描述在編程時出現的大部分異常情況。除此之外,用戶只需繼承Exception類即可自定義異常類。

    • 在程序中使用自定義異常類,大體上可分爲以下幾個步驟:

      • 1.創建自定義異常類;
      • 2.在方法中通過throw關鍵字拋出異常對象;
      • 3.如果在當前拋出異常的方法中處理異常,可以使用try-catch語句塊捕獲並處理,否則在方法的聲明處通過throws關鍵字指明要拋出給方法調用者的異常,
        繼續進行下一步操作。
      • 4.在出現異常方法的調用者中捕獲並處理異常。
    • throws關鍵字通常被應用在聲明方法時,用來指定方法可能拋出的異常。多個異常可使用逗號分隔。

      • 使用throws關鍵字將異常拋給上一級後,如果不想處理該異常,可以繼續向上拋,但最終要有能夠處理該異常的代碼。

      • 如果是Error、RuntimeException或他們的子類,可以不使用throws關鍵字來聲明要拋出的異常,編譯仍能順利通過,但在運行時會被系統拋出。

    • throw關鍵字通常用於方法體中並且拋出一個異常對象。程序在執行到throw語句時立即終止,它後面的語句都不執行。

      • 可以使用多個catch語句來捕捉異常。產生什麼異常,會使程序跳轉到相應的catch異常語句塊中。

      • 由於Exception是所有異常類的父類,如果將catch(Exception e)代碼塊放在其他兩個代碼塊的前面,後面的代碼塊將永遠得不到執行,也就沒有什麼意義了,所以catch語句的順序不可調換。

  • 4,運行時異常

    • RuntimeException異常是程序運行過程中產生的異常。
      Java類庫的每個包中都定義了異常類,所有這些類都是Throwable類的子類。

    • Throwable類派生了兩個子類,分別是Exception和Error類。Error類及其子類用來描述Java運行系統中的內部錯誤以及資源耗盡的錯誤,這類錯誤比較嚴重。

    • Exception類又根據錯誤發生的原因分爲RuntimeException異常和除RuntimeException之外的異常。

    • 5,異常的使用原則

      • Java異常強制用戶去考慮程序的強健性和安全性。

      • 異常處理不應該用來控制程序的正常流程,其主要作用是捕獲程序在運行時發生的異常並進行相應的處理。

      • 編寫代碼處理某個方法可能出現的異常時,可以遵循以下幾條原則:

        • 1.在當前方法聲明中使用try-catch語句捕獲異常。
        • 2.一個方法被覆蓋時,覆蓋它的方法必須拋出相同的異常或異常的子類。
        • 3.如果父類拋出多個異常,則覆蓋方法必須拋出那些異常的一個子集,不能拋出新異常。

第十一章 集合類

  • 1,集合類概述

    • java.util包中提供了一些集合類,這些集合類又被稱爲容器。提到容器不難想到數組,集合類與數組的不同之處是,數組的長度是固定的,集合的長度是可變的;

    • 數組用來存放基本數據類型,集合用來存放對象的引用。

    • 常用的集合有List集合、Set集合和Map集合,其中List與Set繼承了Collection接口,各接口還提供了不同的實現類。

  • 2,Collection接口

    • Collection接口是層次結構中的根接口。構成Collection的單位稱爲元素。

    • Collection接口通常不能直接使用,但該接口提供添加元素、刪除元素、管理數據的方法。

    • 由於List與Set接口都繼承了Collection接口,因此這些方法對List集合與Set集合是通用的。

    • Collection接口中常用的方法:

      • add(E e);//將指定的對象添加到該集合中
      • remove(Object o);//將指定的對象從該集合中移除
      • isEmpty();//返回boolean值,用於判斷當前集合是否爲空
      • iterator();//返回在此Collection的元素上進行迭代的迭代器。用於遍歷集合中的對象。
      • size();//返回int型值,獲取該集合中元素的個數

      • 通常遍歷集合,都是通過迭代器(Iterator)來實現。collection接口中的iterator()方法可返回在此Collection進行迭代的迭代器。

  • 3,List集合

    • List集合包括List接口以及List接口的所有實現類。

    • List集合中的元素允許重複,各元素的順序就是對象插入的順序。類似Java數組,用戶可通過索引(元素在集合中的位置)來訪問集合中的元素。

    • List接口:List接口繼承了Collection接口,因此包含了Collection中的所有方法,此外,List接口還定義了一下兩個非常重要的方法。

      get(int index):獲得指定索引位置的元素
      set(int index,Object obj):將集合中指定索引位置的對象修改爲指定的對象。
      
    • List接口的實現類:List接口的常用實現類有Vector、ArrayList與LinkedList。

      • Vector:內部是數組數據結構,是同步的,增刪,查詢都很慢!

      • ArrayList類內部是數組數據結構,實現了可變的數組,容許保存所有的元素,包括null,並可以根據索引位置對集合進行快速的隨機訪問。缺點是向指定的索引位置插入對象或刪除對象的速度較慢。

      • LinkedList類採用鏈表結構保存對象,是不同步的。這種結構的優點是便於向集合中插入和刪除對象,需要向集合中插入、刪除對象時,使用LinkedList類實現的List集合的效率較高;但對於隨機訪問集合中的對象,使用LinkedList類實現List集合的效率較低。

      • 與數組相同,集合的索引也是從0開始的。

        常用的方法:

        addFirst();addLast();  jdk1.6後爲offerFirst();offerLast();
        
        getFirst();getLast();  jdk1.6後爲peekFirst();peekLast();
        
        removeFirst();removeLast();  jdk1.6後爲pollFirst();pollLast();
        
  • 4,Set集合

    • Set集合中的對象不按特定的方式排序,只是簡單地把對象加入到集合中,但Set集合中不能包含重複對象。Set集合由Set接口和Set接口的實現類組成。

    • Set接口繼承了Collection接口,因此包含collection接口的所有方法。

    • Set接口常用的實現類有HashSet類和TreeSet類:

      • HashSet類:

        • HashSet類實現Set接口,由哈希表(實際上是一個HashMap實例)支持,即內部數據是哈希表,是不同步的。
          它不保證Set的迭代順序,特別是它不保證該順序恆久不變。此類允許使用null元素。

        • 通過對象的hashCode()和equals()方法來完成對象的唯一性。先判斷對象的hashCode值,如果不同,則不用去判斷equals方法;如果相同,再判斷對象的equals方法是否爲true。

        • 記住:如果元素要存儲到HashSet集合中,必須覆蓋hashCode()和equals()方法。

        • 一般情況下,如果定義的類會產生很多對象,比如人,學生等通常都要覆蓋equals和hashCode方法,建立對象判斷是否相同的依據。

      • TreeSet類:

        • TreeSet類不僅實現了Set接口,還實現了java.util.SortedSet接口,因此,TreeSet類實現的Set集合在遍歷集合時按照自然順序遞增排序,也可以按照指定比較器遞增排序,即可以通過比較器對用TreeSet類實現的

        • Set集合中的對象進行排序。
          判斷元素唯一的方式:就是根據比較方法的返回結果是否是0,是0,就是相同元素,不存。

        • TreeSet對元素進行排序的方式一:
          讓元素自身具備比較功能,元素(對象)就要實現Comparable接口,覆蓋compareTo方法。

        • TreeSet集合排序的第二種方式:
          讓集合自身具備比較功能,定義一個類實現Comparator接口,覆蓋compare方法。
          將該類對象作爲參數傳遞給TreeSet集合的構造函數。

  • 5,Map集合

    • Map沒有繼承Collection接口,其提供的是key到value的映射。

    • Map中不能包含相同的key,每個key只能映射一個value。key還決定了存儲對象在映射中的存儲位置,但不是由key對象本身決定的,
      而是通過一種“散列技術”進行處理,產生一個散列碼的整數值,散列碼通常用作一個偏移量,該偏移量對應分配給映射的內存區域的起始位置,從而確定存儲對象在映射中的存儲位置。

    • Map集合包括Map接口以及Map接口的所有實現類。

    • Map接口提供了將key映射到值得對象。一個映射不能包含重複的key,每個key最多隻能映射到一個值。

    • Map接口中提供了集合常用方法:

      • put(K key,V value);//向集合中添加指定的key與value的映射關係

      • containsKey(Object key);//如果此映射包含指定key的映射關係,則返回true

      • containsValue(Object value);//如果此映射將一個或多個key映射到指定值,則返回true

      • get(Object key);//如果存在指定的key對象,則返回該對象對應的值,否則返回null

      • keySet();//返回該集合中的所有key對象形成的Set集合

      • values();//返回該集合中所有值對象形成的Collection集合。
    • Map接口的實現類:Map接口常用的實現類有HashMap和TreeMap

      • 建議用HashMap類實現Map集合,因爲由HashMap類實現的Map集合添加和刪除映射關係效率更高。

      • HashMap是基於哈希表的Map接口的實現,HashMap通過哈希碼對其內部的映射關係進行快速查找;

      • 而TreeMap中的映射關係存在一定的順序,如果希望Map集合中的對象也存在一定的順序,應該使用TreeMap類實現Map集合。

      • HashMap類:該類是基於哈希表的Map接口的實現,此實現提供所有可選的映射操作,並允許使用null值和null鍵,但必須保證鍵的唯一性。

      • HashMap通過哈希表對其內部的映射關係進行快速查找。此類不保證映射的順序,特別是它不保證該順序恆久不變。

      • TreeMap類:該類不僅實現了Map接口,還實現了java.util.SortedMap接口,因此,集合中的映射關係具有一定的順序。

      • 但在添加、刪除和定位映射關係時,TreeMap類比HashMap類性能稍差。

      • 由於TreeMap類實現的Map集合中的映射關係是根據鍵對象按照一定的順序排列的,因此不允許鍵對象是null。

第十二章 泛型技術

  • 在JDK1.5版本中提供了泛型概念,泛型實質上就是使程序員定義安全的類型。

  • 在沒有泛型之前,Java也提供了對Object的引用“任意化”操作,這種任意化操作就是對Object引用進行“向下轉型”及“向上轉型”操作,但某些強制類型轉換的錯誤也許不會被編譯器捕捉,而在運行後出現異常,可見強制類型轉換存在安全隱患,所以在此提供了泛型機制。

  • “向上轉型”是安全的,而如果進行“向下轉型”操作時用錯了類型,或者並沒有執行該操作,就會出現異常。通常並不會出現語法錯誤,所以可以被編譯器接受,但在執行時會出現異常。

  • 泛型的語法爲:類名 T代表一個類型名稱

  • 使用泛型定義的類在聲明該類對象時可以根據不同的需求指定真正的類型,而在使用類中的方法傳遞或返回數據類型時將不再需要進行類型轉換操作,而是使用在聲明泛型類對象時“<>”符號中設置的數據類型。

  • 在定義泛型類時,一般類型名稱使用T來表達,而容器的元素使用E來表達。

  • 泛型的常規用法

    • 1.在定義泛型類時可以聲明多個類型。

    • 語法:

      MutiOverClass<T1,T2>;
      這樣在實例化指定類型的對象時就可以指定多個類如:MutiOverClass<Boolean,Float>=new MutiOverClass<Boolean,Float>();
      
    • 2.定義泛型類時可以聲明數組。

    可以在使用泛型機制時聲明一個數組,但不可以使用泛型來建立數組的實例。

    • 3.集合類聲明容器的元素。

      可以使用K和V兩個字符代表容器中的鍵值和與鍵值相對應的具體值。
      
    • 泛型的高級用法:泛型的高級用法包括限制泛型可用類型和使用類型通配符等。

    • 1.限制泛型可用類型
      語法:class 類名稱;其中anyClass指某個接口或類。
      使用泛型限制後,泛型類的類型必須實現或繼承了anyClass這個接口或類。無論anyClass是接口還是類,在進行泛型限制時都必須使用extends關鍵字。

    • 2.使用類型通配符
      在泛型機制中,提供了類型通配符,其主要作用是創建一個泛型類對象時限制這個泛型類的類型實現或繼承某個接口或類的子類。

      語法:泛型類名稱<? extends List> a=null;
      <? extends List>表示類型未知,但需要使用該泛型對象時,可以單獨實例化。
      這裏需要注意的是,使用通配符聲明的實例化的對象不能對其加入新的信息,只能獲取或刪除。
      
    • 3.泛型類型限制除了可以向下限制之外,還可以進行向上限制,只要在定義時使用super關鍵字即可。

      例如,“A<? super List> a=null;”這樣定義後,對象只接受List接口或上層父類類型。
      
    • 4.繼承泛型類與實現泛型接口
      定義爲泛型的類和接口也可以被繼承與實現。例如:class SubClass

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