在之前Java基礎知識回顧中,我們回顧了基礎資料類型、修飾符和String、三大特性、集合、多線程和IO。本篇文章則對之前學過的知識進行總結。除了簡單的複習之外,還會增加一些相應的了解。
基本資料類型主要有:
byte、short、int、long、float、double、char、boolean
它們可以分為三類:
數值類型:byte、short、int、long、float、double
字元類型:char
布爾型: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
包裝類型有什麼用?
利于實作基本類型之間的轉換;
因為我們了解到基本資料類型之間的互相轉換分為自動類型轉換和強制類型轉換,自動類型轉換還好,但是強制類型轉換容易出現問題。是以出現了包裝類型,它可以很友善的幫助轉換。
例如: String類型的轉int類型可以通過 Integer.parseInt()轉換成int,或使用Integer.valueOf()轉換成Integer類型。
便于函數傳值;
為什麼說方面函數傳值呢?假如一個方法的入參是Object 類型, 但是你的入參是個int類型,是無法直接調用這個方法的,是以這時便可以将int類型的資料進行包裝成Integer類型,在進行調用便可以了。其實除了這個示例,比較常見的是我們的pojo類型,一般會使用包裝類型,這樣的話在便可以使用null來進行判斷。不止這些,在集合的List、Map和Set等等泛型中的類型是,用的是包裝類型,例如: <code>Map<String,Integer> map=new HashMap<String,Integer>();</code>
注意:在使用包裝資料類型進行值比較的時候,用equals進行比較,不要用==。例如:
輸出結果:
Java修飾符主要分為兩類:
通路修飾符
非通路修飾符
其中通路修飾符主要包括 private、default、protected、public。
非通路修飾符主要包括 static、final、abstract、synchronized。
通路修飾符的通路權限:
修飾符
目前類
同一包内
子類
其它包
public
Y
protected
N
default
private
static: 用來修飾類變量和類方法。
修飾變量
static在修飾類變量的時候,無論該類被執行個體化了多少次,它的靜态變量隻有一份拷貝。靜态變量也被稱為類變量。局部變量是不能被聲明為static變量的。
修飾方法
static在修飾類方法的時候,靜态方法是不能使用類的非靜态變量。靜态方法可以直接通過類名調用,是以靜态方法中是不能用this和super關鍵字的。
final :用來修飾類、方法和變量。
final 修飾的類不能夠被繼承,修飾的方法不能被繼承類重新定義,修飾的變量為常量,是不可修改的。
abstract :用來建立抽象類和抽象方法。
修飾類
會使這個類成為一個抽象類,這個類将不能生成對象執行個體,但可以做為對象變量聲明的類型(見後面執行個體),也就是編譯時類型。抽象類就相當于一類的半成品,需要子類繼承并覆寫其中的抽象方法。
會使這個方法變成抽象方法,也就是隻有聲明而沒有實作,需要子類繼承實作。
synchronized: 修飾的方法同一時間隻能被一個線程通路。
transient:被 transient 修飾的執行個體變量時,java 虛拟機(JVM)跳過該特定的變量。
native: 被native修飾的方法實際是由另一種語言進行實作的本地方法
修飾符更詳細的說明:http://www.panchengming.com/2018/03/24/pancm77/
封裝可以被認為是一個保護屏障,防止該類的代碼和資料被外部類定義的代碼随機通路。要通路該類的代碼和資料,必須通過嚴格的接口控制。
使用封裝的好處
良好的封裝能夠減少耦合。
類内部的結構可以自由修改。
可以對成員變量進行更精确的控制。
隐藏資訊,實作細節。
繼承是java面向對象程式設計技術的一塊基石,因為它允許建立分等級層次的類。 繼承就是子類繼承父類的特征和行為,使得子類對象(執行個體)具有父類的執行個體域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。
優缺點
雖然繼承大大提升了代碼的複用性,但是也提高了類之間的耦合性!
多态是指事物在運作過程中存在不同的狀态。
多态的優點
可替換性(substitutability)。多态對已存在代碼具有可替換性。例如,多态對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
可擴充性(extensibility)。多态對代碼具有可擴充性。增加新的子類不影響已存在類的多态性、繼承性,以及其他特性的運作和操作。實際上新加子類更容易獲得多态功能。例如,在實作了圓錐、半圓錐以及半球體的多态基礎上,很容易增添球體類的多态性。
接口性(interface-ability)。多态是超類通過方法簽名,向子類提供了一個共同接口,由子類來完善或者覆寫它而實作的。
靈活性(flexibility)。它在應用中展現了靈活多樣的操作,提高了使用效率。
簡化性(simplicity)。多态簡化對應用軟體的代碼編寫和修改過程,尤其在處理大量對象的運算和操作時,這個特點尤為突出和重要。
三大特性更詳細的說明:http://www.panchengming.com/2018/03/24/pancm78/
List 接口是繼承于 Collection接口并定義 一個允許重複項的有序集合。該接口不但能夠對清單的一部分進行處理,還添加了面向位置的操作。
ArrayList:内部是通過數組實作的,它允許對元素進行快随機通路。當從ArrayList的中間位置插入或者删除元素時,需要對數組進行複制、移動、代價比較高。是以,它适合随機查找和周遊,不适合插入和删除。
LinkedList: 則是連結清單結構存儲資料的,很适合資料的動态插入和删除,随機通路和周遊速度比較慢。另外,他還提供了List接口中沒有定義的方法,專門用于操作表頭和表尾元素,可以當作堆棧、隊列和雙向隊列使用。
Vector: 通過數組實作的,不同的是它支援線程的同步。通路速度ArrayList慢。
推薦單線程使用ArrayList進行查詢和周遊,LinkedList進行插入和删除。
多線程使用Collections.synchronizedList方法對List上鎖,效率比Vector高。
Map 接口并不是 Collection 接口的繼承。Map提供key到value的映射。一個Map中不能包含相同的key,每個key隻能映射一個value。Map接口提供3種集合的視圖,Map的内容可以被當作一組key集合,一組value集合,或者一組key-value映射。
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是一種不包含重複的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。因為Set是一個抽象的接口,是以是不能直接執行個體化一個set對象。<code>Set s = new Set()</code> 這種寫法是錯誤的。
推薦單線程随機查詢用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 接口的方式來建立建立線程。
sleep:在指定的毫秒數内讓目前正在執行的線程休眠(暫停執行),不會釋放對象鎖。
join:指等待t線程終止。
yield:暫停目前正在執行的線程對象,并執行其他線程。
setPriority:設定一個線程的優先級。
interrupt:一個線程是否為守護線程。
wait:強迫一個線程等待。它是Object的方法,也常常和sleep作為比較。需要注意的是wait會釋放對象鎖,讓其它的線程可以通路;使用wait必須要進行異常捕獲,并且要對目前所調用,即必須采用synchronized中的對象。
isAlive: 判斷一個線程是否存活。
activeCount: 程式中活躍的線程數。
enumerate: 枚舉程式中的線程。
currentThread: 得到目前線程。
setDaemon: 設定一個線程為守護線程。(使用者線程和守護線程的差別在于,是否等待主線程依賴于主線程結束而結束)。
setName: 為線程設定一個名稱。
notify(): 通知一個線程繼續運作。它也是Object的一個方法,經常和wait方法一起使用。
多線程更詳細的說明:http://www.panchengming.com/2018/05/28/pancm84/
多線程中經常會使用這幾個關鍵字synchronized、lock和volatile。
synchronized: synchronized是JVM級别的,也就是在運作期由JVM解釋的。它是阻塞鎖(也就是在同一時間隻會有一個線程持有);也是非公平鎖(也就是不遵循先來後到的原則,當一個線程A持有鎖,而線程B、C處于阻塞狀态時,若線程A釋放鎖,JVM将從線程B、C随機選擇一個線程持有鎖并使其獲得執行權)。可以保證原子性、可見性以及有序性。
lock: lock是通過編碼實作的。它是非阻塞鎖;也是公平鎖。可以保證原子性、可見性以及有序性。相比synchronized,更加靈活和強大。
volatile:輕量級的鎖。主要使用者保證共享變量對所有線程的可見性,以及禁止指令重排序)。因為無法保證原子性,是以并不能保證線程安全。
線程安全與共享資源
1.局部變量中的基本資料類型(8種)永遠是線程安全的。
2.局部變量中的對象類型隻要不會被其他線程通路到,也是線程安全的。
3.一個對象執行個體被多個線程同時通路時,他的成員變量就可能是線程不安全的。
IO的名稱又來是Input與Output的縮寫,也就是輸入流和輸出流。輸入流用于從源讀取資料,輸出流用于向目标寫資料。
字元流有兩個抽象類:Writer和Reader類。
其對應子類FileWriter和FileReader可實作檔案的讀寫操作。
BufferedWriter和BufferedReader能夠提供緩沖區功能,用以提高效率。
位元組流也有兩個抽象類:InputStream和OutputStream類。
其對應子類有FileInputStream和FileOutputStream實作檔案讀寫操作。
BufferedInputStream和BufferedOutputStream提供緩沖區功能
推薦讀取文本用字元流,讀取圖檔、視訊和圖檔等二進制檔案用位元組流。
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
如果你對生活感覺到了絕望,請不要氣餒。因為這樣隻會讓你更加絕望!
所謂的希望往往都是在絕望中萌發的,是以,請不要放棄希望!