1. 程式人生 > >Java中基本型別與String在記憶體中的儲存

Java中基本型別與String在記憶體中的儲存

關於在JAVA中基本型別的儲存與String的儲存的問題

主要涉及到堆記憶體和棧記憶體
棧記憶體用來儲存的是基本型別和引用變數(即物件的變數名字)
棧記憶體是用來儲存物件的例項(即new 出來的新物件都由堆記憶體進行儲存)
對於基本型別來說
拿 int 型別舉個例子

i = 1;
j = 1;
在記憶體中的儲存為:首先載入i=1,在棧中沒有i=1,開闢一塊記憶體對1進行儲存然後讓i指向1;
然後在建立j的時候發現棧記憶體中存在了 1 這個記憶體空間,則直接讓j指向1

第二點就是關於 == 與 equals 的區別

== 是比較的兩個變數的引用。如果兩個變數的引用相同的話那麼返回true否則返回false;
equals的比較的內容 在equals的原始碼中通常為
public boolean equals(Object e){
return e instanceof(Integer) && (Integer)e.value == value;
}
這段程式碼的主要的思想就是要判斷:1 是不是同一種類型 2 他們對應的值相不相等 如果全是肯定回答的話那麼這個物件和另一物件就是相等的。

而對於String型別便有所不同

因為String的構造方式有兩種:

一種是字面量構建:即 String a = “taobao”;

另一種的是物件的構建:即 String a = new String(“taobao”);

這兩種方式構建的物件在記憶體中的儲存方式是不同的,對於第一種方式的儲存是直接儲存到棧記憶體當中,跟對基本型別的處理是一樣的。
而對第二種方式的儲存不一樣在於,因為是new建立的物件所以直接把物件儲存到堆的記憶體當中。所以這也就導致了String a = new String(“abc”);
String b = new String(“abc”); a == b //false a.equals(b)//true;
另外值得注意的一點是常量也是儲存在棧記憶體的:比如final String MESSAGE =“abc”;
而對於字串的+(例如"abc"+“bcd”)也是分為兩種情況 這兩種的區別在於一個是直接拿字面量"+" 一個是拿引用變數"+"
第一種情況是 String a = “abc”+“bcd”;
第二種情況是 String a = “abc”;
String b = “bcd”;
String c = a + b ;
這兩種結果的差異在於 第一種的是在編譯的時候編譯器會對兩個字串進行優化,這樣優化完的結果是一個字面量的值即123456存在堆記憶體中
而第二種情況則不是這樣的,第二種情況下的"+"實際是利用了StringBuffer 每次都會建立一個新的物件的然後append().toString();
即 String c = new StringBuffer(abc).append(bcd).toString);這樣創建出來的是一個新的物件所以 c == MESSAGE 為false;

另外是關於String.intern()這個方法。
對於堆記憶體的進行String.intern()返回的是這個根據這個堆記憶體的物件的值去查詢String池中是否有相同的字串(相同的意思是 equals相等),如果有則返回他第一次出現的位置,
然後指向這個引用。

	public class StringTest {
	private static final  String MESSAGE = "taobao";
	public static void main(String[] args){
		
		int i = 10;
		int j = 10;
		System.out.println(i == j);
		System.out.println("-----------");
		String a = "tao" + "bao";
		String b = "tao";
		String c = "bao";	
		System.out.println(a == MESSAGE);
		System.out.println((b+c) == MESSAGE);
		System.out.println("-----------");
		/**
		 * 對應於intern()的程式碼
		 */
		System.out.println((b+c).intern() == a);
		
	}
}

輸出的結果為
在這裡插入圖片描述