小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

java的堆棧機制與String對象

 收藏小管 2017-12-06

轉(zhuǎn)自 :http://blog.csdn.net/zhaolewen/article/details/6718934

首先理解幾個概念:

棧:存放基本類型的變量數(shù)據(jù)和對象的引用,但對象本身不存放在棧中,而是存放在堆(new 出來的對象)或者常量池中(字符串常量對象存放在常量池中。)

當(dāng)在一段代碼塊定義一個變量時,Java就在棧中為這個變量分配內(nèi)存空間,當(dāng)超過變量的作用域后,Java會自動釋放掉為該變量所分配的內(nèi)存空間,該內(nèi)存空間可以立即被另作他用。

堆:存放所有new出來的對象。在堆中分配的內(nèi)存,由Java虛擬機的自動垃圾回收器來管理。

常量池:在堆中分配出來的一塊存儲區(qū)域,存放字符串常量和基本類型常量(public static final)

對于字符串:其對象的引用都是存儲在棧中的,如果是編譯期已經(jīng)創(chuàng)建好(直接用雙引號定義的)的就存儲在常量池中,如果是運行期(new出來的)才能確定的就存儲在堆中。對于equals相等的字符串,在常量池中永遠(yuǎn)只有一份,在堆中有多份

大家先來看看下面這段程序:
public class Test{
    public static void main(String args[])
{
    String str1 = 'abc';
    String str2 = 'abc;
    String str3 = new String('abc');

    System.out.println(str1 == str3);
    System.out.println(str1.equals(str3));
    System.out.println(str2 == str1);
}
}
這段代碼的運行結(jié)果是:
println輸出的是false;而第二句則輸出為true;但是第三句卻是true。

str1,str2是棧內(nèi)變量,它的內(nèi)存保存的是常量池的常量字符串對象對象'abc'的地址
str3是棧內(nèi)變量,它的內(nèi)存保存的是堆中的new String對象的地址,new String在堆中生成對象,并用常量池的字符串對象'abc'初始化堆中的對象,所以堆中的對象的內(nèi)存的內(nèi)容和常量池對象的內(nèi)存的內(nèi)容一樣,但是是不同的兩個對象



在這里很多人會誤認(rèn)為第一句應(yīng)該是true的,但是事實卻是false。這是因為第一句在進行“==”比較的時候比較的是兩個指向,而不是具體指向的內(nèi)容。而第三句在進行“==”比較的時候同樣比較的是指向,但是他們的指向是相同的。這種現(xiàn)象出現(xiàn)的原因和字符串在內(nèi)存中實例化的時候有關(guān)。
具體情況如下圖所示:



當(dāng)執(zhí)行第一句Str1 = 'abc' 實例化出第一個指向;當(dāng)進行第二句Str2 = 'abc' 的時候出現(xiàn)第二個指向,因為堆內(nèi)存中存在'abc',而且str2也沒有new一個新的對象,所以為了節(jié)省內(nèi)存,str2指向了str1所指向的對象;但是第三句的時候出現(xiàn)new語句,他實例化出了一塊新的空間用來盛放'abc',自然str3的指向也也是指向這段新開辟的空間。

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多