Java基礎知識回顧之七 —– 總結篇

虛無境發表於2019-03-03
Java基礎知識回顧之七 —– 總結篇

前言

在之前Java基礎知識回顧中,我們回顧了基礎資料型別、修飾符和String、三大特性、集合、多執行緒和IO。本篇文章則對之前學過的知識進行總結。除了簡單的複習之外,還會增加一些相應的理解。

基礎資料型別

基本資料型別主要有:
byte、short、int、long、float、double、char、boolean
它們可以分為三類:

  1. 數值型別:byte、short、int、long、float、double
  2. 字元型別:char
  3. 布林型:boolean

其中byte是8位,short是16位, int是32位以及 long是64的整數;而float 32位,double 64 位的浮點數。
數值型別的級別從低到高分別為:
byte,char,short(這三個平級)——>int——>float——>long——>double
其中由低階別轉到高階別,是屬於自動型別轉換,這點是由系統自動轉換的。在進行計算的時候,如果級別小於int,最終的資料型別會自動轉換為int,如果高於int,最終資料結果會取其中最高的一個。
又高階別轉到低階別是強制型別轉換強制型別轉換需要注意取值範圍和資料的精確度

char是字元型別,可以儲存任何字元。
boolean是布林型別,只有false或true。

基礎資料型別更詳細的說明:http://www.panchengming.com/2018/03/18/pancm76/

一般我們在用基礎資料型別的時候,也會用到包裝型別。
這裡順便說下包裝型別,也來彌補之前的文章講述不足。

什麼是包裝型別?包裝型別和基礎資料型別的關係。
包裝類就是基本型別資料轉換為物件的一種型別。

每個基本型別在java.lang包中都有一個相應的包裝類。
基礎資料型別:
boolean, char, byte,short,int, long, float,double
分別對應的包裝資料型別:
Boolean,Character,Byte,Short,Integer,Long,Float,Double

包裝型別有什麼用

  1. 利於實現基本型別之間的轉換;
    因為我們瞭解到基本資料型別之間的相互轉換分為自動型別轉換強制型別轉換自動型別轉換還好,但是強制型別轉換容易出現問題。所以出現了包裝型別,它可以很方便的幫助轉換。
    例如: String型別的轉int型別可以通過 **Integer.parseInt()轉換成int,或使用Integer.valueOf()**轉換成Integer型別。

  2. 便於函式傳值;
    為什麼說方面函式傳值呢?假如一個方法的入參是Object 型別, 但是你的入參是個int型別,是無法直接呼叫這個方法的,所以這時便可以將int型別的資料進行包裝成Integer型別,在進行呼叫便可以了。其實除了這個示例,比較常見的是我們的pojo型別,一般會使用包裝型別,這樣的話在便可以使用null來進行判斷。不止這些,在集合的List、Map和Set等等泛型中的型別是,用的是包裝型別,例如: Map<String,Integer> map=new HashMap<String,Integer>();

**注意:在使用包裝資料型別進行值比較的時候,用equals進行比較,不要用==。**例如:

	Integer a=127;
	Integer b=127;
	Integer c=128;
	Integer d=128;
	System.out.println(a == b);
	System.out.println(a.equals(b));
	System.out.println(c == d);
	System.out.println(c.equals(d));
複製程式碼

輸出結果:

true
true
false
true
複製程式碼

修飾符

Java修飾符主要分為兩類:

  • 訪問修飾符
  • 非訪問修飾符

其中訪問修飾符主要包括 private、default、protected、public。
非訪問修飾符主要包括 static、final、abstract、synchronized。

訪問修飾符

訪問修飾符的訪問許可權:

修飾符 當前類 同一包內 子類 其它包
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N

非訪問修飾符

static: 用來修飾類變數和類方法。
修飾變數

static在修飾類變數的時候,無論該類被例項化了多少次,它的靜態變數只有一份拷貝。靜態變數也被稱為類變數。區域性變數是不能被宣告為static變數的。

修飾方法

static在修飾類方法的時候,靜態方法是不能使用類的非靜態變數。靜態方法可以直接通過類名呼叫,因此靜態方法中是不能用thissuper關鍵字的。

final :用來修飾類、方法和變數。

final 修飾的類不能夠被繼承,修飾的方法不能被繼承類重新定義,修飾的變數為常量,是不可修改的。

abstract :用來建立抽象類和抽象方法。
修飾類

會使這個類成為一個抽象類,這個類將不能生成物件例項,但可以做為物件變數宣告的型別(見後面例項),也就是編譯時型別。抽象類就相當於一類的半成品,需要子類繼承並覆蓋其中的抽象方法。

修飾方法

會使這個方法變成抽象方法,也就是隻有宣告而沒有實現,需要子類繼承實現。

synchronized: 修飾的方法同一時間只能被一個執行緒訪問。

transient:被 transient 修飾的例項變數時,java 虛擬機器(JVM)跳過該特定的變數。

native: 被native修飾的方法實際是由另一種語言進行實現的本地方法

修飾符更詳細的說明:http://www.panchengming.com/2018/03/24/pancm77/

三大特性

封裝

封裝可以被認為是一個保護屏障,防止該類的程式碼和資料被外部類定義的程式碼隨機訪問。要訪問該類的程式碼和資料,必須通過嚴格的介面控制。

使用封裝的好處

  1. 良好的封裝能夠減少耦合。

  2. 類內部的結構可以自由修改。

  3. 可以對成員變數進行更精確的控制。

  4. 隱藏資訊,實現細節。

繼承

繼承是java物件導向程式設計技術的一塊基石,因為它允許建立分等級層次的類。
繼承就是子類繼承父類的特徵和行為,使得子類物件(例項)具有父類的例項域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。

優缺點

雖然繼承大大提升了程式碼的複用性,但是也提高了類之間的耦合性!

多型

多型是指事物在執行過程中存在不同的狀態。

多型的優點

  1. 可替換性(substitutability)。多型對已存在程式碼具有可替換性。例如,多型對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
  2. 可擴充性(extensibility)。多型對程式碼具有可擴充性。增加新的子類不影響已存在類的多型性、繼承性,以及其他特性的執行和操作。實際上新加子類更容易獲得多型功能。例如,在實現了圓錐、半圓錐以及半球體的多型基礎上,很容易增添球體類的多型性。
  3. 介面性(interface-ability)。多型是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。
  4. 靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。
  5. 簡化性(simplicity)。多型簡化對應用軟體的程式碼編寫和修改過程,尤其在處理大量物件的運算和操作時,這個特點尤為突出和重要。

三大特性更詳細的說明:http://www.panchengming.com/2018/03/24/pancm78/

集合

List

List 介面是繼承於 Collection介面並定義 一個允許重複項的有序集合。該介面不但能夠對列表的一部分進行處理,還新增了面向位置的操作。

List的常用類

  • ArrayList:內部是通過陣列實現的,它允許對元素進行快隨機訪問。當從ArrayList的中間位置插入或者刪除元素時,需要對陣列進行復制、移動、代價比較高。因此,它適合隨機查詢和遍歷,不適合插入和刪除。
  • LinkedList: 則是連結串列結構儲存資料的,很適合資料的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List介面中沒有定義的方法,專門用於操作表頭和表尾元素,可以當作堆疊、佇列和雙向佇列使用。
  • Vector: 通過陣列實現的,不同的是它支援執行緒的同步。訪問速度ArrayList慢。

推薦單執行緒使用ArrayList進行查詢和遍歷,LinkedList進行插入和刪除。
多執行緒使用Collections.synchronizedList方法對List上鎖,效率比Vector高。

Map

Map 介面並不是 Collection 介面的繼承。Map提供key到value的對映。一個Map中不能包含相同的key,每個key只能對映一個value。Map介面提供3種集合的檢視,Map的內容可以被當作一組key集合,一組value集合,或者一組key-value對映。

Map常用類

  • HashMap: HashMap的鍵是根據HashCode來獲取,所以根據鍵可以很快的獲取相應的值。不過它的鍵物件是不可以重複的,它允許鍵為Null,但是最多隻能有一條記錄,不過卻是可以允許多條記錄的值為Null。因為HashMap是非執行緒安全的,所以它的效率很高。
  • TreeMap:可以將儲存的記錄根據鍵進行排序,預設是按鍵值的升序排序(自然順序)。也可以指定排序的比較器,當用Iterator遍歷TreeMap時,得到的記錄是排過序的。它也是不允許key值為空,並且不是執行緒安全的。
  • LinkedHashMap:LinkedHashMap基本和HashMap一致。不過區別在與LinkedHashMap是維護一個雙連結串列,可以將裡面的資料按寫入 的順序讀出。可以認為LinkedHashMap是HashMap+LinkedList。即它既使用HashMap運算元據結構,又使用LinkedList維護插入元素的先後順序。它也不是執行緒安全的。
  • Hashtable:Hashtable與HashMap類似,可以說是HashMap的執行緒安全版。不過它是不允許記錄的鍵或者值為null。因為它支援執行緒的同步,是執行緒安全的,所以也導致了Hashtale在效率較低。
  • ConcurrentHashMap: ConcurrentHashMap在Java 1.5作為Hashtable的替代選擇新引入的。使用鎖分段技術技術來保證執行緒安全的,可以看作是Hashtable的升級版。

推薦單執行緒隨機查詢用HashMap,自然順序或自定義順序用TreeMap,插入和刪除用LinkedHashMap。
多執行緒推薦使用ConcurrentHashMap。

Set

Set是一種不包含重複的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。因為Set是一個抽象的介面,所以是不能直接例項化一個set物件。Set s = new Set() 這種寫法是錯誤的。

推薦單執行緒隨機查詢用HashSet,自然順序或自定義順序用TreeSet,插入和刪除用LinkedHashSet。

集合更詳細的說明:http://www.panchengming.com/2018/04/19/pancm80/

多執行緒

多執行緒是指在同一程式中有多個順序流在執行。 簡單的說就是在一個程式中有多個任務執行。

執行緒的狀態

建立(new)狀態: 準備好了一個多執行緒的物件
就緒(runnable)狀態: 呼叫了start()方法, 等待CPU進行排程
執行(running)狀態: 執行run()方法
阻塞(blocked)狀態: 暫時停止執行, 可能將資源交給其它執行緒使用
終止(dead)狀態: 執行緒銷燬

執行緒的建立

  • 通過實現 Runnable 介面;
  • 通過繼承 Thread 類本身;
  • 通過實現 Callable介面,然後與Future 和建立執行緒。

注:執行緒啟動的方法是start而不是run。
推薦建立單執行緒的時候使用繼承 Thread 類方式建立,多線執行緒的時候使用Runnable、Callable 介面的方式來建立建立執行緒。

執行緒的常用方法

  1. sleep:在指定的毫秒數內讓當前正在執行的執行緒休眠(暫停執行),不會釋放物件鎖。
  2. join:指等待t執行緒終止。
  3. yield:暫停當前正在執行的執行緒物件,並執行其他執行緒。
  4. setPriority:設定一個執行緒的優先順序。
  5. interrupt:一個執行緒是否為守護執行緒。
  6. wait:強迫一個執行緒等待。它是Object的方法,也常常和sleep作為比較。需要注意的是wait會釋放物件鎖,讓其它的執行緒可以訪問;使用wait必須要進行異常捕獲,並且要對當前所呼叫,即必須採用synchronized中的物件。
  7. isAlive: 判斷一個執行緒是否存活。
  8. activeCount: 程式中活躍的執行緒數。
  9. enumerate: 列舉程式中的執行緒。
  10. currentThread: 得到當前執行緒。
  11. setDaemon: 設定一個執行緒為守護執行緒。(使用者執行緒和守護執行緒的區別在於,是否等待主執行緒依賴於主執行緒結束而結束)。
  12. setName: 為執行緒設定一個名稱。
  13. notify(): 通知一個執行緒繼續執行。它也是Object的一個方法,經常和wait方法一起使用。

多執行緒更詳細的說明:http://www.panchengming.com/2018/05/28/pancm84/

多執行緒中經常會使用這幾個關鍵字synchronizedlockvolatile
synchronized: synchronized是JVM級別的,也就是在執行期由JVM解釋的。它是阻塞鎖(也就是在同一時間只會有一個執行緒持有);也是非公平鎖(也就是不遵循先來後到的原則,當一個執行緒A持有鎖,而執行緒B、C處於阻塞狀態時,若執行緒A釋放鎖,JVM將從執行緒B、C隨機選擇一個執行緒持有鎖並使其獲得執行權)。可以保證原子性、可見性以及有序性。

lock: lock是通過編碼實現的。它是非阻塞鎖;也是公平鎖。可以保證原子性、可見性以及有序性。相比synchronized,更加靈活和強大。

volatile:輕量級的鎖。主要使用者保證共享變數對所有執行緒的可見性,以及禁止指令重排序)。因為無法保證原子性,所以並不能保證執行緒安全。

執行緒安全與共享資源
1.區域性變數中的基本資料型別(8種)永遠是執行緒安全的。
2.區域性變數中的物件型別只要不會被其他執行緒訪問到,也是執行緒安全的。
3.一個物件例項被多個執行緒同時訪問時,他的成員變數就可能是執行緒不安全的。

IO流

IO的名稱又來是Input與Output的縮寫,也就是輸入流和輸出流。輸入流用於從源讀取資料,輸出流用於向目標寫資料。

字元流

字元流有兩個抽象類:WriterReader類。
其對應子類FileWriterFileReader可實現檔案的讀寫操作。
BufferedWriterBufferedReader能夠提供緩衝區功能,用以提高效率。

位元組流

位元組流也有兩個抽象類:InputStreamOutputStream類。
其對應子類有FileInputStreamFileOutputStream實現檔案讀寫操作。
BufferedInputStreamBufferedOutputStream提供緩衝區功能

推薦讀取文字用字元流,讀取圖片、視訊和圖片等二進位制檔案用位元組流

IO流更詳細的說明:http://www.panchengming.com/2018/06/16/pancm85/

說起IO流,順便談下它的幾個孿生兄弟,NIO、BIO和AIO。

IO:

阻塞的,從硬碟讀取資料時,程式一直等待,資料讀完在繼續操作 。
操作時一次一個位元組的讀取資料,一個輸出流一次輸出一個位元組資料,一個輸出流一次消耗一個位元組資料,資料的讀取和寫入效率不好。
I/O屬於底層操作,效能依賴與系統環境。

NIO:

同步非阻塞I/O,在讀取資料時程式可以繼續執行,讀取玩資料以後,通知當前程式(即硬體的中斷,軟體中的回撥),然後程式立即或執行完後處理資料。選擇器(selector)、緩衝(buffer)、管道(channel) 面向塊(緩衝區)。採取“預讀方式”。操作中一步產生或消費一個資料塊,按塊處理資料,同時資料讀取到一個稍後可能會處理的緩衝區,需要時也可在緩衝區前後移動。
方式適用於連線數目多且連線比較短(輕操作)的架構。例如聊天工具。畢竟好用的框架Netty和Mina。

BIO:

同步並阻塞,伺服器實現模式為一個連線一個執行緒,即客戶端有連線請求時伺服器端就需要啟動一個執行緒進行處理,如果這個連線不做任何事情會造成不必要的執行緒開銷,當然可以通過執行緒池機制改善。
方式適用於連線數目比較小且固定的架構

AIO:

非同步非阻塞,伺服器實現模式為一個有效請求一個執行緒,客戶端的I/O請求都是由OS先完成了再通知伺服器應用去啟動執行緒進行處理.。
方式使用於連線數目多且連線比較長(重操作)的架構。

簡單的介紹了下這些知識。詳細的可以檢視這篇文章:https://blog.csdn.net/huangwenyi1010/article/details/75577091?ref=myread

其它

Java基礎知識的總結篇就介紹到這裡了,以後的博文主要編寫的方向是Java的進階知識了,主要內容為設計模式,原始碼解析和併發程式設計這塊吧!至於後面的這些博文沒有信心能夠寫好,畢竟這些相對於來說還是比較難以理解的。所以以後的這些相關博文我會按照自己的理解寫的,如果寫的不好,還請多多指點!

原創不易,如果感覺不錯,希望給個推薦!您的支援是我寫作的最大動力!
版權宣告:
作者:虛無境
部落格園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm    
個人部落格出處:http://www.panchengming.com

相關文章