1. 程式人生 > >JAVA中的String類

JAVA中的String類

優缺點 equal 由於 基本數據 alt 特點 成員 地址 對象分配

  • String類的特點?

  1. String類是final類,也即意味著String類不能被繼承,並且它的成員方法都默認為final方法。
  2. String類其實是通過char數組來保存字符串的。
  3. String對象一旦被創建就是固定不變的了,對String對象的任何改變都不影響到原對象,相關的任何change操作都會生成新的對象。
  • 字符串常量池?

  1. 我們知道字符串的分配和其他對象分配一樣,是需要消耗高昂的時間和空間的,而且字符串我們使用的非常多。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和==?

  • 對於==,如果作用於基本數據類型的變量(byte,short,char,int,long,float,double,boolean ),則直接比較其存儲的"值"是否相等;如果作用於引用類型的變量(String),則比較的是所指向的對象的地址(即是否指向同一個對象)。
  • equals方法是基類Object中的方法,因此對於所有的繼承於Object的類都會有該方法。在Object類中,equals方法是用來比較兩個對象的引用是否相等,即是否指向同一個對象。
  • 對於equals方法,註意:equals方法不能作用於基本數據類型的變量。如果沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址;而String類對equals方法進行了重寫,用來比較指向的字符串對象所存儲的字符串是否相等。其他的一些類諸如Double,Date,Integer等,都對equals方法進行了重寫用來比較指向的對象所存儲的內容是否相等。

  創建字符串的方式? 

  1. 單獨使用""引號創建的字符串都是常量,編譯期就已經確定存儲到String Pool中;
  2. 使用new String("")創建的對象會存儲到heap中,是運行期新創建的;
  3. 使用只包含常量的字符串連接符如"aa" + "aa"創建的也是常量,編譯期就能確定,已經確定存儲到String Pool中;
  4. 使用包含變量的字符串連接符如"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類