棧內存:
在函數中定義的一些基本類型的變量和對象的引用變量都在函數的棧內存中分配。 棧內存主要存放的是基本類型類型的數據 如、( int, short, long, byte, float, double, boolean, char) 和對象句柄。並無有String基本類型、在棧內存的數據的大小及生存週期是必須肯定的、其優勢是寄存速度快、、棧數據能夠共享、缺點是數據固定、不夠靈活。
棧的共享:
String a = "abc";
String b = "abc";
System.out.println(a==b);
結果爲true 這就說明了a b其實指向同一個值
注意,咱們這裏並不用a.equals(b);的方式,由於這將比較兩個字符串的值是否相等。==號,根據JDK的說明,只有在兩個引用都指向了同一個對象時才返回真值。而咱們在這裏要看的是,a與b是否都指向了同一個對象。
結果說明,JVM建立了兩個引用a和b,但只建立了一個對象,並且兩個引用都指向了這個對象。
首先它會在棧中建立一個變量爲a的引用,而後查找棧中是否有abc這個值,若是沒找到,就將abc存放進來,而後將a指向abc。接着處理String b = "abc";在建立完b的引用變量後,由於在棧中已經有abc這個值,便將b直接指向abc。這樣,就出現了a與b同時指向abc
特別注意的是,這種字面值的引用與類對象的引用不一樣。假定兩個類對象的引用同時指向一個對象,若是一個對象引用變量修改了這個對象的內部狀態,那麼另外一個對象引用變量也即刻反映出這個變化。相反,經過字面值的引用來修改其值,不會致使另外一個指向此字面值的引用的值也跟着改變的狀況。如上例,咱們定義完a與b的值後,再令a=abcd;那麼,b不會等於abcd,仍是等於abc。在編譯器內部,遇到a= abcd;時,它就會從新搜索棧中是否有abcd的字面值,若是沒有,從新開闢地址存放abcd的值;若是已經有了,則直接將a指向這個地址。所以a值的改變不會影響到b的值。
堆內存:
堆內存用來存放全部new 建立的對象和 數組的數據、
String a = new String ("abc");
String b = "abc";
System.out.println(a==b); //False
String a = new String ("abc");
String b = new String ("abc");
System.out.println(a==b); //False
建立了兩個引用。建立了兩個對象。兩個引用分別指向不一樣的兩個對象。以上兩段代碼說明,只要是用new()來新建對象的,都會在堆中建立,並且其字符串是單獨存值的,即便與棧中的數據相同,也不會與棧中的數據共享。 數組
原文出自:http://www.douban.com/note/199184450/ 函數