Java編程思想(後)
持有對象
- 若是一個程序只包含固定數量的且其生命期都是已知的對象,那麼這是一個很是簡單的程序。
- Java中的庫基本類型: List, Set, Queue和Map --- 稱爲集合類.
- ArrayList用add()插入對象, 用get()訪問這些對象。
- 若是一個類沒有顯式地聲明繼承那個類, 那麼它自動繼承自Object.
- Java 泛型穿件類會很是複雜, 預約義的泛型會很簡單。
- 經過泛型, 能夠在編譯器防止將錯誤類型的對象置到容器中。
- 泛型對應的是編譯器錯誤, 而不是運行時錯誤。
- foreach語法來選擇一個List中的每一個元素。
- Object有默認的toString()方法。
- Java容器類庫的用途是保存對象:
- Collection: 一個獨立元素的序列, List, Queue, Set。
- Collection接口歸納了序列的概念, 一種存放一組對象的方式。
- List不關心是否存在重複。
- Map: 一組成對的鍵值對對象, 容許使用鍵來查找值(字典)。
- Collection: 一個獨立元素的序列, List, Queue, Set。
- 任何容器類, 都必須有某種方式能夠插入元素將他們再次取回, 持有事物是容器最基本的工做。
- 迭代器(也是一種設計模式): 是一個對象, 它的工做是變量並選擇序列中的對象, 而不用直到或關心序列底層的結構。
- 迭代器一般被稱爲輕量級對象, 建立代價小。
- Java的Iterator只能單向移動, 這個Iterator只能用來:
- 使用方法iterator()要求容器返回一個Iterator, Iterator將返回序列的第一個元素。
- 使用next()得到序列中的下一個元素。
- 使用hasNext()檢查序列中是否還有元素。
- 使用remove()將迭代器最近返回的元素刪除。
- iterator可以將遍歷序列的操做與序列底層的結構分離。
- ListIterator是一個更強大的Iterator的子類型, 它只能用於各類List類的訪問。
- ListIterator能夠雙向移動。
- LinkedList還添加了可使其用做棧、隊列或雙端隊列的方法。
- 棧一般是指先進先出(LIFO)的容器, 有時棧也被稱爲疊加棧, 最後壓入棧的元素, 第一個被彈出。
- Collection是描述全部序列容器的共性的根接口,它可能會被認爲是一個附屬接口, 由於要表示其餘若干個接口的共性而出現的接口。
java.util.AbstactCollection
類提供了Collection的默認實現。
經過異常處理錯誤
-
Java的異常處理機制創建在C++的基礎之上, 使用異常可以下降錯誤處理代碼的複雜度。java
-
異常機制可以保證捕獲每一個錯誤。程序員
-
基本異常: 異常情形(exceptional condition)是阻止當前方法或做用域繼續執行的問題。正則表達式
- 當拋出異常後, Java將使用new在堆上建立異常對象, 當前執行路徑被終止, 而且當前環境中彈出對異常對象的引用, 異常處理機制接管程序, 並開始尋找一個恰當的地方來繼續執行程序。--- 這個恰當的地方就是異常處理程序, 程序要麼換一種方式運行, 要麼繼續運行下去。
- 異常容許強制程序中止運行, 並告訴出現了什麼問題, 或者強制程序處理問題, 並返回到穩定狀態。
- 全部異常類都有兩個構造器: 一個是默認構造器; 另外一個是接受字符串做爲參數, 以便把相關信息放入異常對象的構造器。
- 使用new建立了異常對象後, 此對象的引用將傳給throw。
- 能夠把異常簡單地看做是一種不一樣的返回機制, 還能用拋出異常的方式從當前的做用域退出。返回一個異常對象, 而後退出方法或做用域。
- Throwable對象是異常類型的根類。
-
捕獲異常:數據庫
- 異常是如何被捕獲的, 必須首先理解監控區域(guarded region)的概念; --- 它是一段可能產生異常的代碼, 後面需緊跟處理這些異常的代碼。
- try塊: 若是在方法中拋出了異常, 這個方法將在拋出異常的過程當中結束。
- catch塊: 異常處理程序, 每一個catch子句(異常處理程序)看起來就像是接收一個且僅接收一個特殊類型參數的方法。
-
終止與恢復:編程
- 異常處理理論上有兩種基本模型: Java支持終止模型(Java和C++所支持的模型) --- 假設錯誤很是關鍵, 程序沒法返回到異常發生的地方繼續執行, 一旦異常拋出,就代表錯誤已沒法挽回, 也不能繼續執行。
- 恢復模型: 異常處理程序的工做是修正錯誤, 而後從新嘗試調用出問題的方法, 並認爲第二次能成功。恢復模型一般但願異常被處理以後能繼續執行程序 --- 碰見錯誤時不能拋出異常, 而是調用方法來修正該錯誤。
- 或者把try塊放到while循環中, 直到獲得滿意的結果。
- 異常處理理論上有兩種基本模型: Java支持終止模型(Java和C++所支持的模型) --- 假設錯誤很是關鍵, 程序沒法返回到異常發生的地方繼續執行, 一旦異常拋出,就代表錯誤已沒法挽回, 也不能繼續執行。
-
編譯器建立了默認構造器, 他講自動調用基類的默認構造器, 對異常來講, 最重要的部分是類名。設計模式
-
異常與記錄日誌:數組
- Java可使用呢
java.util.logging
工具將輸出記錄到日誌中。
- Java可使用呢
-
捕獲全部異常:安全
catch(Exception e) {System.out.println("Caught an exception");}
-
利用
throw e
從新拋出異常。工具 -
異常使用指南:ui
- 應該在下列狀況下使用異常:
- 在恰當的級別處理問題。(在直到該如何處理的狀況下才捕獲異常)。
- 解決問題並從新調用產生異常的方法。
- 進行少量修補, 而後繞過異常發生的地方繼續執行。
- 用別的數據進行計算, 以代替方法預計會返回的值。
- 把當前運行環境下能作的事情儘可能作完, 而後把相同(不一樣)的異常重拋到更高層。
- 終止程序。
- 進行簡化。
- 讓類庫和程序更安全。
- 應該在下列狀況下使用異常:
字符串
- 字符串操做是極端及程序設計中最多見的行爲。
- String對象是不可變的, 每一個方法都會建立一個全新的String對象, 以包含修改後的字符串內容。
- 重載'+'與StringBuilder: String對象具備只讀特性, 指向它的任何引用都不可能改變它的值。
- JDK自帶的工具javap能夠反編譯代碼
javap -c Concatenation
--- 將生成JVM字節碼。 - Java中的每一個類從根本上都是繼承自Object, 標準容器類天然也不例外。--- 都有toString()方法。
正則表達式
-
正則表達式已經整合到標準Unix工具集之中, 例如sed和awk, 正則表達式是一種強大而靈活的文本處理工具。
-
split()方法,其功能是將字符串從正則表達式匹配的地方切開。
-
\\
表示在正則表達式中插入一個普通(字面上的)反斜槓。 -
組是用括號來劃分的正則表達式, 能夠根據組的編號來引用每一個組,0表示整個組, 1表示第一對括號裏的組。
-
StringReader將String轉換可讀的流對象。
-
Scanner的構造器能夠接受任何類型的輸入對象, 包括File對象, InputStream, String或者Readable對象。
- 有了Scanner, 全部的輸入, 分詞以及翻譯的操做都隱藏在不一樣類型的next方法中。
- Scanner類能夠減輕輸入的負擔。
類型信息
- 運行時類型信息使得能夠在程序運行時發現和使用類型信息。 --- RTTI(Run-Time Type Identification)。
- Class對象包含了與類有關的信息。 --- Class對象就是用來建立類的全部的常規對象的。
- Class類還擁有大量的使用RTTI的其餘方式。
- 類是程序的一部分,每一個類都有一個Class對象; 每當編寫而且編譯了一個新類,就會產生一個Class對象(被保存一個同名的.class文件中)。
- 爲了生成這個類的對象,運行這個程序的Java虛擬機(JVM)將使用被稱爲"類加載器"的子系統。
- 類加載器子系統實際上能夠包含一條類加載器鏈,可是隻有一個原生類加載器,它是JVM實現的一部分。
- 全部的類都是在對其第一次使用時, 動態加載到JVM中。建立第一個類的靜態成員的引用時, 就會加載這個類。
- new操做符建立類的新對象也會被看成對類的靜態成員的引用。
- Java程序在它開始運行以前並不是被徹底加載, 其各個部分是在必須時才加載的。
- 類加載器首先檢查一個類的Class對象是否已經加載, 若是還沒有加載, 默認的類加載器就會根據類名查找
.class
文件。- 某個附加類加載器可能會在數據庫中查找字節碼。
- 類加載器首先檢查一個類的Class對象是否已經加載, 若是還沒有加載, 默認的類加載器就會根據類名查找
- 類字面常量:
- Java還提供了另外一種方法來生成對Class對象的引用, 即便用類字面常量
FancyToy.class
。 - 類字面常量不只能夠應用於普通的類,也能夠應用與接口,數組以及基本數據類型。
- 另外,對於基本數據類型的包裝器類,還有一個標準字段TYPE。
- TYPE字段是一個引用,指向對應的基本數據類型的Class。
- Java還提供了另外一種方法來生成對Class對象的引用, 即便用類字面常量
- 爲了使用類而作的準備工做實際包含三個步驟:
- 加載: 加載器執行,查找字節碼,並從字節碼中建立一個Class對象。
- 連接: 在連接階段將驗證類中的字節碼, 爲靜態域分配存儲空間,若是必要的話,將解析這個類建立這個類對其餘類的全部索引。
- 初始化: 若是這個類是超類(父類), 則對其初始化,執行靜態初始化器和靜態初始化塊。
- 初始化被延遲到對靜態方法(構造器隱式地是靜態的)或者很是數靜態域進行首次引用時才執行。
- 泛化的Class引用: class引用老是指向某個Class對象,能夠製造類的實例, 幷包含可用做與這些實例的全部方法代碼。
- Class引用表示的就是它所指向的對象的確切類型,而該對象即是Class類的一個對象。
- 利用cast方法進行轉型。
- instanceof與Class的等價性。
- RTTI的前提是, 這個類在編譯時必須是已知的。
- 動態代理。
- 空對象 --- null。
- interface關鍵字的一種重要目標就是容許程序員隔離構建, 進而下降耦合性。
- instanceof關鍵字返回一個布爾值,告訴咱們對象是否是某個特定類型的實例。
- 工廠方法設計模式: 將對象的建立工做交給類本身去完成。
- 工廠方法能夠被多態地調用, 從而建立恰當的對象。
泛型
- 通常的類和方法, 只能使用具體的類型: 要麼是基本類型, 要麼是自定義的類。若是要編寫能夠應用於多種類型的代碼, 這種限制對代碼的約束會很大。
- 在面向對象編程中, 多態是一種泛化機制。
- final類不能擴展, 其餘任何類均可以被擴展。
- 泛型實現了參數化類型的概念, 是代碼能夠運用於多種類型, 但願類或方法具備最普遍的表達能力。
- Java的泛型相比C++來講要弱不少。 --- 理解邊界所在,只有知道一個技術不能作什麼,才能更好地作到所能作的。
- 元組(tuple):是將一組對象直接打包存儲於其中的一個單一對象,容許讀取其中元素,但不容許向其中存放新的對象。(數據傳送對象)。
- 泛型也能夠應用於接口, 例如生成器(generator) --- 專門負責建立對象的類。
- 泛型的主要目的之一就是用來指定容器要持有什麼類型的對象,並且由編譯器來保證類型的正確性。
- Java泛型的核心概念: 告訴編譯器想使用什麼類型, 而後編譯器幫助處理一切細節。 --- 能夠簡單地認爲泛型和其餘類型差很少,只是多了參數列表而已。
- 聲明爲final的元素便不能再賦予其餘值了。
- 基本類型不能做爲泛型的類型參數。
- 建立一個適配器(adapter)來實現所需的接口。
- static方法,沒法訪問泛型類的類型參數, 若是static方法須要使用泛型能力,就必須使其成爲泛型方法。
- 在使用泛型類時, 必須在建立對象的時候指定類型參數的值,而使用泛型方法的時候,一般沒必要指明參數類型, 由於編譯器會自動找出具體的類型, --- 類型參數腿短(type arguement inference)。
- 編譯器可以從泛型參數列表中的一個參數推斷出另外一個參數。
- 泛型方法與可變參數可以很好地共存。
- 生成某個類對象的類,必須具有兩個特色:
- 它必須聲明爲public;
- 必須具有默認的構造器(無參數的構造其)。
- 泛型的一個重要好處是可以簡單而安全地建立複雜的模型。
泛型方法
- 泛型方法使方法可以獨立於類而產生變化。
- 使用泛型方法能夠取代將整個類泛型化。
- 在泛型代碼內部,沒法得到任何有關泛型參數類型的信息。
- Java泛型重用了extends關鍵字。
- 無界通配符
<?>
看起來意味着任何事物, <?>能夠被認爲是一種裝飾。 - 混型的價值之一是它們能夠將特性和行爲一致地應用與多個類之上。
數組
- 數組與其餘容器之間的區別有三方面: 效率, 類型和保存基類類型的能力.
- 數組是一種效率最高的存儲和隨機訪問對象引用序列的方式.
- ArrayList.
- 數組是第一級對象.
- 返回一個數組.
- 多維數組.
- 數組與泛型.
- Arrays實用功能.
容器深刻研究
- 完整的容器分類法
- 散列與散列碼 --- HashMap.
Java I/O系統
- File類
- Reader和Writer.