參考鏈接: Java中的StringBuilder類及其示例
Java基礎知識及其擴展筆記
?零 l? 寫在前面一 l? JVM1、【1.1.2.1】java程序運行的一般流程2、【1.1.2.1】JVM一般運行流程3、【1.1.2.1】JIT(just in time 即時編譯編譯器)4、堆與棧
??
? 二 l? Java 基礎1、【1.1.4】Java的類不能多繼承,接口可以2、【1.1.4】Java的字符串有length()方法得到長度,所以不用在最后加上'\0'結束符3、【1.1.7】java的包和javax的包沒有差別4、【1.2.1】變量空間5、【1.2.4】關鍵字是特殊的標識符,標識符是變量、方法等的名字6、【1.2.7】泛型與類型擦除7、【1.2.8】==與equals8、【1.2.9】equals與hashcode9、【1.4.2】形參是傳實參的值還是實參的引用10、【1.4.4】淺拷貝、深拷貝11、【2.4】接口、抽象類細化比較12、【2.5.1】String、StringBuffer、StringBuilder分析13、【2.5.2】Object 類的常見方法
??
? 三 l? Java 面向對象1、【2.2.2】繼承tips2、【2.2.3】多態tips
??
? 四 l? Java 核心技術1、【3.1.1】Collections 工具類和 Arrays 工具類常見方法2、【3.2.1】Java異常類層次結構圖3、【3.2.3】try-catch-finally4、【3.3.1】程序、進程、線程5、【3.4】文件與I\O流
??
?
?
??
?學習教程:
[Java基礎知識]
??
?
零 l? 寫在前面?
?
1、對“Java基礎知識”中的一些擴展,有意思的文中和文外內容都會記錄下來。 ? ? ? ? ??
一 l? JVM?
?
1、【1.1.2.1】java程序運行的一般流程?
.java源代碼文件 ——JDK中的javac粗編譯——》.class字節碼文件 ——JVM解釋或編譯——》二進制機器碼?
??
2、【1.1.2.1】JVM一般運行流程?
讀取.class字節碼文件,使用解釋器逐行解釋執行?
??
3、【1.1.2.1】JIT(just in time 即時編譯編譯器)?
JIT是JVM的一部分,使用編譯的方式提高JVM執行代碼的速度。 當某行代碼或某個函數調用次數過多(已經執行很多次后),JVM會使用JIT將.class中的對應代碼塊進行編譯,下次直接使用編譯后的文件。?
?
?如果某次循環的時候JIT遍歷的循環內的代碼塊,則下次執行時優先使用編譯后的二進制文件,而不會進行逐行解釋。? ?擴展鏈接:深入淺出 JIT 編譯器及其優化策略 JIT優化策略概括來說就是:選擇合適的編譯模式(client/server)、提高編譯后代碼的存儲空間、調整編譯閾值、調整編譯線程數?
?
4、堆與棧?
簡單來說?
?棧堆訪問速度快慢空間小大(理論上可以使用全部虛擬內存)對應變量(一般情況)沒有new的變量new的變量例子簡單類型、數組或對象的引用new的一個類
對于 String數組 ,如果 不new 則數組實體指向 棧的常量池(指向的是個地址) ;new 的話數組實體在 堆 。 其他類型數組 無論是否new ,數組引用都在棧,數組實體都在堆。?
?
?在如下代碼中,user是User類實例的一個引用,所以在棧里;user指向的User實例是new出來的,所以在堆里。?
?User user = new User();
?
?擴展鏈接[堆棧的詳細區別]?
?
? ? ? ? ??
二 l? Java 基礎?
?
1、【1.1.4】Java的類不能多繼承,接口可以?
??
2、【1.1.4】Java的字符串有length()方法得到長度,所以不用在最后加上’\0’結束符?
??
3、【1.1.7】java的包和javax的包沒有差別?
??
4、【1.2.1】變量空間?
基本類型含義大小默認值最小值最大值包裝類型包裝類型常量池大小boolean布爾類型數組中1byte / 單個變量4bytefalsefalsetrueBooleantrue/falsechar單個字符2byte / 16bits‘u0000’0216-1Character[0, 127]byte字節整形1byte / 8bits0-128127Byte[-128, 127]short短整形2byte / 16bits0-215 / -32768215-1 / 32767Short[-128, 127]int整形4byte / 32bits0-231 / 約-2.1*109231-1 / 約2.1*109Integer[-128, 127]long長整形8byte / 64bits0L-263 / 約-9.2*1018263-1 / 約9.2*1018Long[-128, 127]float單精度浮點數4byte / 32bits0fIEEE754IEEE754Float無double雙精度浮點數8byte / 64bits0dIEEE754IEEE754Double無void空Void
?
?boolean的大小:在數組中為了存儲方便,一般會轉換成byte類型;在單個變量中為了比較方便,一般會轉換成int類型?
?
??
5、【1.2.4】關鍵字是特殊的標識符,標識符是變量、方法等的名字?
常見的關鍵字(紅色字體為容易忽略的內容):?
?
?方法: 表示實例方法和靜態方法都可以使用 變量、類變量、引用變量: 都是變量,因為java中都是對象,所以變量都是類變量;變量的實質就是引用,所以又可以說是引用變量 成員變量: 定義在類內函數外的變量,默認自動賦默認值(final必須顯式賦值) 局部變量: 定義在函數內的變量,不會自動賦值?
?
關鍵字類型關鍵字約束范圍解釋訪問控制private成員變量 / 方法 / 類私有,不允許用在局部變量【允許訪問修改范圍:同一類內】default默認的訪問控制權限【允許訪問修改范圍:同一包內】protected成員變量 / 方法 / 類保護,不允許用在局部變量【允許訪問修改范圍:同一包內、不同包的子類】public成員變量 / 方法 / 類 / 接口公開,不允許用在局部變量【允許訪問修改范圍:所有地方】類、方法、變量修飾符class類說明正在定義一個類abstract類限定這個類或方法是抽象的 [擴展鏈接:abstract詳解]extends子類繼承一個父類,只能繼承一個interface接口說明正在定義一個接口接口方法默認都是public abstract接口變量默認都是public static final[擴展鏈接:abstract與interface的區別]implements類說明此類實現了什么接口final變量 / 方法 / 類引用為基本數據類型,該引用為常量無法修改。引用為引用數據類型,引用指向地址不能更改,地址里的內容可以修改。修飾方法時,方法可以被繼承,不能被重寫。修飾類時,無法被繼承。【不常用】native方法JNI(Java Native Interface Java本地接口)與c/c++聯合開發時才會使用new變量創建一個已定義的類實例 [擴展鏈接:new是如何實現的]static成員變量 / 靜態方法不允許用在局部變量,方便在沒有創建對象的情況下來進行調用(方法/變量)static不允許用來修飾局部變量[擴展鏈接:Java中的static關鍵字解析]【不常用】strictfp類 / 接口(strict float point 精確浮點),嚴格使用IEEE754定義進行計算【不常用】transient變量標識變量不會輸入到流中(不能串行化),如網絡流、文件流synchronized方法 / 代碼塊在并行中同步方法或代碼塊(同一時間只能有一個線程調用)[擴展鏈接:synchronized實現原理]【不常用】volatile保證可見性和一定的有序性,不能保證原子性在JMM(Java內存模型中),如果一個線程先去寫一個變量,然后一個線程去進行讀取,那么寫入操作肯定會先行發生于讀操作[擴展鏈接:volatile關鍵字解析]程序控制break方法跳出最內層循環continue方法省略循環體內的后續步驟,進入下一次循環return方法直接結束方法if、else方法判斷語句 if {} else if {} else {}switch、case、default方法跳轉語句,常用來優化多重if elseswitch(條件){case ...: break; case default: break;}switch條件可以為byte、short、int、char、enum、String(JDK7)do、while方法循環語句,do{干活}while(條件) 或 while(條件){干活}for方法循環語句,for( 條件(略) ) {干活}instanceof方法A instanceof B判斷A是否是B的類實例、子類、接口實現類(A能否轉換為B)是則返回true,否則返回false(大白話就是A是不是跟B有關,且B比A的“大”)錯誤處理try、catch、finally方法錯誤處理,try {干活} catch(Exception e) {處理異常} finally {無論是否異常都會執行的代碼}throw方法體程序員主動拋出的異常,示例:throw new NumberFormatException(); throws方法頭定義方法時預先聲明可能會拋出的異常包相關package.java文件開頭聲明當前包路徑import.java文件開頭導入依賴包基本類型略略boolean、byte、char、short、int、long、float、double、null、true、false變量引用super類內使用父類的成員屬性或者成員方法(能否使用以屬性或方法的訪問控制關鍵字為準)this類內使用當前實例的屬性,示例:this.userNamevoid方法說明返回值為空保留字goto、const不允許使用c/c++中的goto不在java中被允許;c/c++中的const在java中為final關鍵字?
?
?默認類加載順序: ——》父類static方法 ——》子類static方法 ——》父類參數初始化 ——》父類無參構造器初始化 ——》子類參數初始化 ——》子類無參構造器初始化?
?
擴展:某些關鍵字的具體使用范圍?
關鍵字使用范圍
??
6、【1.2.7】泛型與類型擦除?
(1)常用通配符:T、E、K、V、??
(2)泛型最大的作用是用來給編譯器檢查的,編譯后(.class文件)中會將泛型替換為最接近的共同父類?
(3).java文件中,子類重寫父類的泛型方法。 ??? .class文件中,子類重載了父類的方法,同時將父類方法指向子類的方法,使其最終的結果與重寫相同。?
(4)泛型不能是基本數據類型,泛型最大的父類就是Object,Object不能存儲某個數,只能引用某個對象?
(5)[擴展鏈接:Java泛型類型擦除以及類型擦除帶來的問題] ??
7、【1.2.8】==與equals?
?==equals基本數據類型比較值不能比較引用數據類型比較地址沒有重寫equals方法:比較地址重寫equals方法:根據方法比較
?
?注意: String類型不new的時候是從常量池從取值的,所以地址一樣。即a==b為true?
?String a = "aaa";
String b = "aaa";
?
?
??
8、【1.2.9】equals與hashcode?
(1)equals和hashcode都是Object類的方法,所有的類都會帶這兩個方法?
(2)對于復雜類的equals效率可能低,所以可以使用hashcode快速粗篩選 ??? 示例:HashSet檢查重復就是先使用hashcode再使用equals?
(3)hashcode()一般將int類型的散列碼后返回,默認是對堆上的對象生成盡量不相同的特殊值,所以重寫了equals()也要重寫hashcode(),不然內容相同的對象hashcode不同,容易出bug。(比如HashSet里面添加了兩個有相同數據的對象)?
(4)[擴展鏈接:hashCode()和equals()的若干問題解答] ??
9、【1.4.2】形參是傳實參的值還是實參的引用?
對于基本數據類型和對象,都是是傳值,只不過對象傳的是對象地址(可以看做是引用,本質上是傳的地址值,還是傳值)。 所以形參修改對象成員值,實參也會跟著改變,因為指向的都是同一個對象。但是形參改變對象引用不會影響實參所指的對象引用。 ??
10、【1.4.4】淺拷貝、深拷貝?
?淺拷貝深拷貝基本數據類型傳遞值傳遞值引用數據類型傳遞引用new一個新對象并拷貝所有內容
??
11、【2.4】接口、抽象類細化比較?
接口是特殊的抽象類,所以更加嚴格?
?接口抽象類繼承impelement 多繼承entends 單繼承限定符public、protected、defaultpublic、protected、default變量類型static final普通變量方法聲明抽象方法、默認方法(JDK8)、靜態方法(JDK8)、私有方法(JDK9)、私有靜態方法(JDK9)抽象方法、非抽象方法方法實現不允許允許實現約束要實現所有方法不用實現所有方法
??
12、【2.5.1】String、StringBuffer、StringBuilder分析?
?StringStringBufferStringBuilder數據可變性不可變可變可變線程安全性安全安全不安全速度慢,要new個String對象中快,比 StringBuffer 快10~15%使用場景少量數據多線程大量數據單線程大量數據
String類的源碼中,使用private final char value[]來存儲數據?
?
?JDK9中使用private final byte value[]來存儲數據 StringBuffer和StringBuilder都繼承自AbstractStringBuilder?
?
??
13、【2.5.2】Object 類的常見方法?
方法類型具體定義解釋常用方法(可重寫)public native int hashCode()返回當前對象的hash值public boolean equals(Object obj)默認是比較兩個對象的地址是否相同,String類重寫了此方法用來比較字符串public String toString()默認是返回類的名字@實例的哈希碼的16進制字符串(默認返回地址)System.out輸出對象時默認調用類的toString方法protected native Object clone() throws CloneNotSupportedException返回當前對象的深拷貝常用方法(不可重寫)public final native Class<?> getClass()返回當前對象的class對象等待方法(不可重寫)public final void wait() throws InterruptedException暫停線程執行并釋放所占用的鎖(sleep不會釋放占用的鎖),會一直等待直到喚醒public final native void wait(long timeout) throws InterruptedException功能同上(timeout是等待時間)public final void wait(long timeout, int nanos) throws InterruptedException功能同上(nanos表示更精確的等待時間(納秒),范圍0~999999)喚醒方法(不可重寫)public final native void notify()喚醒 一個 在此對象監視器(鎖)上等待的線程public final native void notifyAll()喚醒 所有 在此對象監視器(鎖)上等待的線程銷毀方法(可重寫)protected void finalize() throws Throwable { }實例被垃圾回收器回收時自動調用?
? ? ? ? ??
三 l? Java 面向對象?
?
Java性能差的主要原因不是因為Java是面向對象的語言,而是因為Java是半編譯語言,編譯出來的.class文件不是二進制文件,而是要繼續編譯或解釋。 ??
1、【2.2.2】繼承tips?
子類擁有父類所有的屬性和方法(包含私有的內容),但是根據訪問控制前綴來判斷能否訪問。 ??
2、【2.2.3】多態tips?
父類的引用指向子類的實例才叫多態,如List<Integer> list = new ArrayList<Integer>(); (此時的引用不能調用子類獨有的方法,有重寫方法會調用重寫方法,類型轉換回子類后可以調用子類獨有的方法) ? ? ? ? ??
四 l? Java 核心技術?
?
1、【3.1.1】Collections 工具類和 Arrays 工具類常見方法?
要用的時候再查,直接看也記不住。 [擴展鏈接:Collections工具類和Arrays工具類常見方法] ??
2、【3.2.1】Java異常類層次結構圖?
?Errors類是 程序無法處理的異常 ,碰到Error的時候虛擬機一般會直接終止線程。?
Exceptions類是 程序可以處理的異常?
在Exceptions類下的Check Exceptions是編譯的時候檢查的異常,Uncheck Exceptions是運行時的異常 ??
3、【3.2.3】try-catch-finally?
注意:finally是在函數返回之前做的,所以會覆蓋try或catch里面的return?
建議:使用try-with-resources替代try-catch-finally?
try-catch-finally寫法:?
//讀取?本?件的內容
Scanner scanner = null;
try {
? ? scanner = new Scanner(new File("D://read.txt"));
? ? while (scanner.hasNext()) { System.out.println(scanner.nextLine()); }
} catch (FileNotFoundException e) {
? ? e.printStackTrace();
} finally {
? ? if (scanner != null) {
? ? ? ? scanner.close();
? ? }
}
?
try-with-resources寫法 (需要類實現AutoCloseable接口) :?
try (Scanner scanner = new Scanner(new File("test.txt"))) {
? ? while (scanner.hasNext()) { System.out.println(scanner.nextLine()); }
} catch (FileNotFoundException e) {
? ? e.printStackTrace();
}
?
??
4、【3.3.1】程序、進程、線程?
程序:在數據存儲設備中的靜態代碼?
進程:程序被操作系統載入到內存中運行?
線程:共享進程資源的cpu最小執行單位 線程狀態:[圖片來源] ??
5、【3.4】文件與I\O流?
流分類:?
流的流向操作單元流的角色劃分輸入流字節流節點流輸出流字符流處理流
4個抽象基類:?
?
?InputStream:字節輸入流 OutputStream:字節輸出流 Reader:字符輸入流 Writer:字符輸出流?
?
傳輸字符的時候為了防止亂碼或轉換問題,使用字符流;其他時候使用字節流。?
操作對象字節輸入流字節輸出流字符輸入流字符輸出流文件FileInputStreamFileOutputStreamFileReaderFileWriter基本數據類型DataInputStreamDataOutputStream數組ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter對象序列化操作ObjectInputStreamObjectOutputStream緩沖控制BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter字節流轉字符流InputStreamReaderOutputStreamWriter打印控制printStreamprintWriter管道操作(不推薦在同一個線程中使用,容易死鎖)PipedInputStreamPipedOutputStreamPipedReaderPipedWriter