1. 程式人生 > >JAVA字串的兩種定義方式的區別

JAVA字串的兩種定義方式的區別

關於JAVA中兩種字串定義方式的區別

第一次寫,就當複習總結一下,希望能幫到需要的人吧= =

我們知道在JAVA中,對於字串的例項化方式有兩種:

  • 直接賦值:String str = “Hello World”;
  • 構造方法例項化:String str = new String(“Hello World”); 對於這兩種例項化有何區別,首先我們先來聊一聊直接賦值的方式 觀察下面的例子:
public class StringDemo{
	public static void main(String[] args) {
		String str1 = "Hello qty";
		String str2 =
"Hello qty"; String str3 = "Hello qty"; String str4 = "Hello ytq"; System.out.println(str1==str2); System.out.println(str1==str3); System.out.println(str2==str3); System.out.println(str1==str4); } }

對於以上的輸出結果 true true true false “==”雖然是一種字串的比較,但是它實際上比較的並不是字串的內容,而比較的是它們所在的記憶體地址的數值。可能會有疑惑,字串的直接賦值,會產生一個新的堆記憶體空間

,那麼這裡應該產生了三塊堆記憶體空間,並且有不同的三個記憶體地址才對,但這裡為什麼會出現str1和str2和str3的記憶體地址是相同的呢? 先來個記憶體圖簡單說明一下,在這裡字串的直接賦值方式,會給字串賦予一個“名字”(其實就是堆記憶體的地址),並且開闢一段新的堆記憶體(存資料)。 在這裡插入圖片描述 畫圖水平一般,將就看吧,為什麼這裡會出現str1,str2,str3同時指向同一塊堆記憶體?

因為這裡JAVA存在著共享設計池的概念

什麼是共享設計模式? 在JVM底層實際會存在一個物件池,在使用者通過直接賦值的方式定義了字串時,這時候該字串對應的匿名物件(在上述案例中就是Hello qty和Hello ytq,字串常量就是對應的String類的匿名物件- -)自動“入池儲存

”,倘若後續過程中使用者再次直接賦值定義了字串並且還使用了相同的內容,那麼將不再開闢新的堆記憶體,而是令其指向原來已經入池的物件進行引用。 因為字串的值一旦設定將無法改變,因此,JAVA的設計者認為共享的設計方式,可以帶來更高的效率。

  • 接下來說說構造方法例項化字串的方式 String str = new String(“Hello qty”); 在這裡插入圖片描述

看到這裡就已經很清楚構造方法例項化這種方式比較於直接賦值的缺陷所在,由於同時開闢了兩塊堆記憶體空間,有一塊會被當做垃圾空間等待GC處理回收。 再來觀察一段構造方法例項化字串的程式碼:

public class StringDemo{
	public static void main(String[] args) {
	String str1 = new String("Hello qty");
	String str2 = "Hello qty";
	System.out.println(str1==str2);
	}
}

對於以上輸出結果: false 在這裡為什麼不像上面的例子一樣,str1和str2同時指向一塊堆記憶體空間呢? 所以這也是構造方法例項化字串的缺點之一,它不會將其內容自動儲存在物件池當中,所以在這裡相當於每一個str都指向各自的堆記憶體空間,因此記憶體地址不同,從而出現false。

以上就可以分析出構造方法例項化字串與直接賦值操作的優劣所在,那麼構造方法例項化是否也可以進行物件的入池操作呢? 入池方法:public String intern();

public class StringDemo{
	public static void main(String[] args) {
	String str1 = new String("Hello qty").intern();
	String str2 = "Hello qty";
	System.out.println(str1==str2);
	}
}

輸出結果: true 這裡將構造方法例項化的str1的匿名物件進行手工入池,這樣自然和str2指向的記憶體空間是相同的,這種操作可以有,但沒必要。

綜上,直接賦值的方式確實優於構造方法的方式,因此字串在使用時都使用的是直接賦值的方法。