標籤:包含 string類 相等 執行 等價 數組 高效能 obj new
- String類是final類,也即意味著String類不能被繼承,並且它的成員方法都預設為final方法。
- String類其實是通過char數組來儲存字串的。
- String對象一旦被建立就是固定不變的了,對String對象的任何改變都不影響到原對象,相關的任何change操作都會產生新的對象。
- 我們知道字串的分配和其他對象分配一樣,是需要消耗高昂的時間和空間的,而且字串我們使用的非常多。JVM為了提高效能和減少記憶體的開銷,在執行個體化字串的時候進行了一些最佳化:使用字串常量池。每當我們建立字串常量時,JVM會首先檢查字串常量池,如果該字串已經存在常量池中,那麼就直接返回常量池中的執行個體引用。如果字串不存在常量池中,就會執行個體化該字串並且將其放到常量池中。由於String字串的不可變性我們可以十分肯定常量池中一定不存在兩個相同的字串。
String a="AA";
String b="AA";
String c=new String("AA");
a、b和字面上的AA都是指向JVM字串常量池中的"AA"對象,他們指向同一個對象。
new關鍵字一定會產生一個對象AA,同時這個對象是儲存在堆中。所以上面這一句應該產生了兩個對象:儲存在方法區中字串常量池的AA和儲存堆中AA。但是在Java中根本就不存在兩個完全一模一樣的字串對象。故堆中的AA應該是引用字串常量池中AA。所以c、堆AA、池AA的關係應該是:c--->堆AA--->池AA。
雖然a、b、c、c是不同的引用,但是從String的內部結構我們是可以理解上面的。String c = new String("AA");雖然c的內容是建立在堆中,但是他的內部value還是指向JVM常量池的AA的value,它構造AA時所用的參數依然是AA字串常量。
字串池的優缺點?
- 字串池的優點就是避免了相同內容的字串的建立,節省了記憶體,省去了建立相同字串的時間,同時提升了效能;另一方面,字串池的缺點就是犧牲了JVM在常量池中遍曆對象所需要的時間,不過其時間成本相比而言比較低。
equals和==?
- 對於==,如果作用於基礎資料型別 (Elementary Data Type)的變數(byte,short,char,int,long,float,double,boolean ),則直接比較其儲存的"值"是否相等;如果作用於參考型別的變數(String),則比較的是所指向的對象的地址(即是否指向同一個對象)。
- equals方法是基類Object中的方法,因此對於所有的繼承於Object的類都會有該方法。在Object類中,equals方法是用來比較兩個對象的引用是否相等,即是否指向同一個對象。
- 對於equals方法,注意:equals方法不能作用於基礎資料型別 (Elementary Data Type)的變數。如果沒有對equals方法進行重寫,則比較的是參考型別的變數所指向的對象的地址;而String類對equals方法進行了重寫,用來比較指向的字串對象所儲存的字串是否相等。其他的一些類諸如Double,Date,Integer等,都對equals方法進行了重寫用來比較指向的對象所儲存的內容是否相等。
建立字串的方式?
- 單獨使用""引號建立的字串都是常量,編譯期就已經確定儲存到String Pool中;
- 使用new String("")建立的對象會儲存到heap中,是運行期新建立的;
- 使用只包含常量的字串串連符如"aa" + "aa"建立的也是常量,編譯期就能確定,已經確定儲存到String Pool中;
- 使用包含變數的字串串連符如"aa" + s1建立的對象是運行期才建立的,儲存在heap中;
String、StringBuffer、StringBuilder的區別?
- 可變與不可變:String是不可變字串對象,StringBuilder和StringBuffer是可變字串對象(其內部的字元數組長度可變)。
- 是否多安全執行緒:String中的對象是不可變的,也就可以理解為常量,顯然安全執行緒。StringBuffer 與 StringBuilder 中的方法和功能完全是等價的,只是StringBuffer 中的方法大都採用了synchronized 關鍵字進行修飾,因此是安全執行緒的,而 StringBuilder 沒有這個修飾,可以被認為是非安全執行緒的。
- String、StringBuilder、StringBuffer三者的執行效率如下:
- StringBuilder > StringBuffer > String 當然這個是相對的,不一定在所有情況下都是這樣。比如String str = "hello"+ "world"的效率就比 StringBuilder st = new StringBuilder().append("hello").append("world")要高。因此,這三個類是各有利弊,應當根據不同的情況來進行選擇使用:
- 當字串相加操作或者改動較少的情況下,建議使用 String str="hello"這種形式;
- 當字串相加操作較多的情況下,建議使用StringBuilder,如果採用了多線程,則使用StringBuffer。
JAVA中的String類