天天看點

Java中可變類型和不可變類型

<span style="font-family:Microsoft YaHei;font-size:14px;">public class Test {
	public int num;
	public static void main(String[] args) {
		Test t = new Test();
		t.num = 11;
		Test t1 = t;
		t1.num = 111;
		System.out.println(t.num);
	}
}//輸出結果是111</span>           

在聲明這裡的對象時,對象t和t1的值其實是一個位址,也可以看成一個指向堆記憶體中某個對象的指針。讓t1=t時,實際上也是讓t1指向t指向的對象,通過t1改變num的值,也就是改變了堆記憶體中的對象的值,通過t再調用時,num的值自然也是改變後的結果。

<span style="font-family:Microsoft YaHei;font-size:14px;">public class Test_1 {
	public static void main(String[] args) {
		int i = 0;
		int i1 = i;
		i1 = 10;
		System.out.println(i);
	}
}//輸出結果仍然是0</span>           

如果傳遞的是基本資料類型,就不會出現這樣的情況,雖然i1=i的時候,i1和i共用0,但是一旦i1指派10,此時不是将記憶體中的0改成10,而是又建立一個10,讓i1指向10,而i還是指向0的,是以最後的結果還是0,String類型也是不可變的,原理跟int是相同的。

看下面一段代碼:

<span style="font-family:Microsoft YaHei;font-size:14px;">public class Test_PinJieZiFuChuan {
	public static void main(String[] args) {
		String s = "A";
		for (int i = 0; i < 1000; i++) {
			s = s + i;
		}
		System.out.println(s);
	}
}</span>           

這是一段拼接字元串的代碼,這段代碼的運作效率是很低的,因為在運作過程中,記憶體不斷建立新的對象,在for循環中一共建立了1000個對象,當然一旦對象使用完之後虛拟機還要負責回收對象,是以Java中有StringBuffer來解決這個問題。

總結下到底什麼是“不可變”類型:

以String為例,String s = "sssss"建立了一個"sssss"字元串,不可變不是指s一旦被建立成"sssss"之後就不能再給其他值,我完全可以再寫s="sssssbbbbb";這裡的不可變是指,一旦建立之後,s指向的"sssss"是不可變的,你無法在記憶體中,把"sssss"改成"sssssbbbbb"來改變s的值,隻能建立一個新的字元串"sssssbbbbb"來讓s等于這個值。