基礎學習筆記(二)-java

11.字符編碼
System.out.println("系統(tǒng)默認編碼:"+
         System.getProperty("file.encoding");//獲取本地系統(tǒng)默認編碼
//系統(tǒng)默認編碼:UTF-8 (從JDK1.9起)

ISO8859-1:一種國際通用的單字節(jié)編碼,最多只能表示0~255的字符范圍,主要在英文傳輸中使用;
GBK/GB2312:中文的國標編碼,專門用來表示漢字,是雙字節(jié)編碼,如果在此編碼器中出現(xiàn)了中文,則使用ISO8859-1編碼。GBK可以表示簡體中文和繁體中文,而GB2312只能表示簡體中文,GBK兼容GBK2312;
UNICODE:十六進制編碼,可以準確地表示出任何語言文字,此編碼不兼容ISO8859-1編碼;
UTF-8編碼:由于UNICODE不支持ISO8859-1編碼,而且占用空間較多,英文字母也需要雙字節(jié)去編碼,不便于存儲和傳輸,于是產生了UTF編碼。UTF兼容ISO8859-1編碼,同時也可以用來表示所有語言字符,但是UTF編碼是不定長的編碼,每一個字符的長度從1~6個字節(jié)不等,一般在中文網(wǎng)頁使用此編碼,可以節(jié)省空間。

12.String.intern()

https://blog.csdn.net/tyyking/article/details/82496901

new String都是在堆上創(chuàng)建字符串對象。當調用 intern() 方法時,編譯器會將字符串添加到常量池中(stringTable維護),并返回指向該常量的引用。
JDK 1.7后,intern方法還是會先去查詢常量池中是否有已經(jīng)存在,如果存在,則返回常量池中的引用,這一點與之前沒有區(qū)別,區(qū)別在于,如果在常量池找不到對應的字符串,則不會再將字符串拷貝到常量池,而只是在常量池中生成一個對原字符串的引用。簡單的說,就是往常量池放的東西變了:原來在常量池中找不到時,復制一個副本放到常量池,1.7后則是將在堆上的地址引用復制到常量池。

Q:下列程序的輸出結果:
String s1 = “abc”;
String s2 = “abc”;
System.out.println(s1 == s2);
A:true,均指向常量池中對象。

Q:下列程序的輸出結果:
String s1 = new String(“abc”);
String s2 = new String(“abc”);
System.out.println(s1 == s2);
A:false,兩個引用指向堆中的不同對象。

Q:下列程序的輸出結果:
String s1 = “abc”;
String s2 = “a”;
String s3 = “bc”;
String s4 = s2 + s3;
System.out.println(s1 == s4);
A:false,因為s2+s3實際上是使用StringBuilder.append來完成,會生成不同的對象。

Q:下列程序的輸出結果:
String s1 = “abc”;
final String s2 = “a”;
final String s3 = “bc”;
String s4 = s2 + s3;
System.out.println(s1 == s4);
A:true,因為final變量在編譯后會直接替換成對應的值,所以實際上等于s4=”a”+”bc”,而這種情況下,編譯器會直接合并為s4=”abc”,所以最終s1==s4。

Q:下列程序的輸出結果:
String s = new String(“abc”);
String s1 = “abc”;
String s2 = new String(“abc”);
System.out.println(s == s1.intern());
System.out.println(s == s2.intern());
System.out.println(s1 == s2.intern());
A:false,false,true。
13.類加載的準備階段

https://www.cnblogs.com/chanshuyi/p/jvm_serial_07_jvm_class_loader_mechanism.html

當完成字節(jié)碼文件的校驗之后,JVM 便會開始為類變量分配內存并初始化。這里需要注意兩個關鍵點,即內存分配的對象以及初始化的類型。
內存分配的對象:Java 中的變量有「類變量」和「類成員變量」兩種類型,「類變量」指的是被 static 修飾的變量,而其他所有類型的變量都屬于「類成員變量」。在準備階段,JVM 只會為「類變量」分配內存,而不會為「類成員變量」分配內存。「類成員變量」的內存分配需要等到初始化階段才開始。
初始化的類型:在準備階段,JVM 會為類變量分配內存,并為其初始化。但是這里的初始化指的是為變量賦予 Java 語言中該數(shù)據(jù)類型的零值,而不是用戶代碼里初始化的值。但如果一個變量是常量(被 static final 修飾)的話,那么在準備階段,屬性便會被賦予用戶希望的值。

14. Java類體中只能有變量定義和成員方法的定義,不能有單獨的語句,要放在方法體里

在Java 中創(chuàng)建類之后,還需要為類添加類體,類體主由成員變量和方法兩部分組成。
在Java 的類中定義成員變量和方法的類聲明格式如下:
其中:
. 成員變量名1、成員變量名2……成員變量名n 是類的成員變量,數(shù)據(jù)類型可以是基本的數(shù)據(jù)類型,也可以是對象類型。
. 成員方法名1 是類的成員方法,返回值類型是通過該方法獲得值的數(shù)據(jù)類型,方法體是該方法要執(zhí)行的語句,返回值就是調用該方法得到的值。
. 成員方法名2 是類的成員方法,void 表示該方法沒有返回值,方法體是該方法要執(zhí)行的語句。

15.類加載相關

https://www.cnblogs.com/chanshuyi/p/jvm_serial_07_jvm_class_loader_mechanism.html

對于靜態(tài)字段,只有直接定義這個字段的類才會被初始化(執(zhí)行靜態(tài)代碼塊)。因此通過其子類來引用父類中定義的靜態(tài)字段,只會觸發(fā)父類的初始化而不會觸發(fā)子類的初始化。

一個類的執(zhí)行順序大概可以按照如下步驟:

1.確定類變量的初始值。在類加載的準備階段,JVM 會為類變量初始化零值,這時候類變量會有一個初始的零值。如果是被 final 修飾的類變量,則直接會被初始成用戶想要的值。
2.初始化入口方法。當進入類加載的初始化階段后,JVM 會尋找整個 main 方法入口,從而初始化 main 方法所在的整個類。當需要對一個類進行初始化時,會首先初始化類構造器(),之后初始化對象構造器()。
3.初始化類構造器。JVM 會按順序收集類變量的賦值語句、靜態(tài)代碼塊,最終組成類構造器由 JVM 執(zhí)行。
4.初始化對象構造器。JVM 會按照收集成員變量的賦值語句、普通代碼塊,最后收集構造方法,將它們組成對象構造器,最終由 JVM 執(zhí)行。
如果在初始化 main 方法所在類的時候遇到了其他類的初始化,那么就先加載對應的類,加載完成之后返回。如此反復循環(huán),最終返回 main 方法所在類。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容