<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    例子說明String的堆(heap)棧(stack)信息

         String是一個特殊的包裝類數據。即可以用String str = new String("abc");的形式來創建,也可以用String str = "abc";的形式來創建。前者是規范的類的創建過程,即在Java中,一切都是對象,而對象是類的實例,全部通過new()的形式來創建。Java 中的有些類,如DateFormat類,可以通過該類的getInstance()方法來返回一個新創建的類,似乎違反了此原則。其實不然。該類運用了單 例模式來返回類的實例,只不過這個實例是在該類內部通過new()來創建的,而getInstance()向外部隱藏了此細節。那為什么在String str = "abc";中,并沒有通過new()來創建實例,是不是違反了上述原則?其實沒有。

      關于String str = "abc"的內部工作。Java內部將此語句轉化為以下幾個步驟:
    (1)先定義一個名為str的對String類的對象引用變量:String str;
    (2)在棧中查找有沒有存放值為"abc"的地址,如果沒有,則開辟一個存放字面值為"abc"的地址,接著創建一個新的String類的對象o,并 將o 的[url=]字符串[/url]值指向這個地址,而且在棧中這個地址旁邊記下這個引用的對象o。如果已經有了值為"abc"的地址,則查找對象o,并返 回o的地址。
    (3)將str指向對象o的地址。
    值得注意的是,一般String類中字符串值都是直接存值的。但像String str = "abc";這種場合下,其字符串值卻是保存了一個指向存在棧中數據的引用!
      
    為了更好地說明這個問題,我們可以通過以下的幾個代碼進行驗證。

    String str1 = "abc";
    String str2 = "abc";
    System.out.println(str1==str2);  //true
       
    注意,我們這里并不用str1.equals(str2);的方式,因為這將比較兩個字符串的值是否相等。==號,根據JDK的說明,只有在兩個引用都指向了同一個對象時才返回真值。而我們在這里要看的是,str1與str2是否都指向了同一個對象。
        圖解:
        
    結果說明,JVM創建了兩個引用str1和str2,但只創建了一個對象,而且兩個引用都指向了這個對象。

    我們再來更進一步,將以上代碼改成:

    String str1 = "abc";
    String str2 = "abc";
    str1 = "bcd";
    System.out.println(str1 + "," + str2);  //bcd, abc
    System.out.println(str1==str2);  //false

    這就是說,賦值的變化導致了類對象引用的變化,str1指向了另外一個新對象!而str2仍舊指向原來的對象。上例中,當我們將str1的值改為"bcd"時,JVM發現在棧中沒有存放該值的地址,便開辟了這個地址,并創建了一個新的對象,其字符串的值指向這個地址。
    事實上,String類被設計成為不可改變(immutable)的類。如果你要改變其值,可以,但JVM在運行時根據新值悄悄創建了一個新對象,然 后將這個對象的地址返回給原來類的引用。這個創建過程雖說是完全自動進行的,但它畢竟占用了更多的時間。在對時間要求比較敏感的環境中,會帶有一定的不良 影響。

    再修改原來代碼:

    String str1 = "abc";
    String str2 = "abc";
      
    str1 = "bcd";
      
    String str3 = str1;
    System.out.println(str3);  //bcd

    String str4 = "bcd";
    System.out.println(str1 == str4);  //true
       
       
    str3 這個對象的引用直接指向str1所指向的對象(注意,str3并沒有創建新對象)。當str1改完其值后,再創建一個String的引用str4,并指向 因str1修改值而創建的新的對象。可以發現,這回str4也沒有創建新的對象,從而再次實現棧中數據的共享。

    我們再接著看以下的代碼。

    String str1 = new String("abc");
    String str2 = "abc";
    System.out.println(str1==str2);  //false



    創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。

    String str1 = "abc";
    String str2 = new String("abc");
    System.out.println(str1==str2);  //false

    創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。

    以上兩段代碼說明,只要是用new()來新建對象的,都會在堆中創建,而且其字符串是單獨存值的,即使與棧中的數據相同,也不會與棧中的數據共享。

    posted on 2008-09-04 14:22 nonels 閱讀(496) 評論(0)  編輯  收藏 所屬分類: J2SE

    <2008年9月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

    導航

    統計

    常用鏈接

    留言簿(2)

    隨筆分類(16)

    隨筆檔案(16)

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 朝桐光亚洲专区在线中文字幕 | 在线观看肉片AV网站免费 | 免费成人在线观看| 亚洲成_人网站图片| 久久久久久精品免费免费自慰| 亚洲a一级免费视频| 香蕉免费一区二区三区| 亚洲精品线在线观看| 99久热只有精品视频免费看| 久久99国产亚洲精品观看| 国产va在线观看免费| 亚洲A∨无码一区二区三区| 永久在线观看www免费视频| 亚洲理论精品午夜电影| 中文毛片无遮挡高潮免费| 亚洲av无码一区二区三区观看| 成人毛片免费在线观看| 青青免费在线视频| 久久亚洲精品视频| 91九色老熟女免费资源站| 亚洲熟妇丰满xxxxx| 四虎影视免费永久在线观看| a级毛片免费观看在线| 亚洲AV电影院在线观看| 18禁止观看免费私人影院| 亚洲AV无码一区二区三区网址| 四虎永久免费地址在线网站| 在线观看片免费人成视频无码| 久久精品a亚洲国产v高清不卡| 一二三四免费观看在线电影| 亚洲日韩中文字幕无码一区| 精品国产日韩亚洲一区| 无码国产精品一区二区免费式芒果 | 成年人免费网站在线观看| 国产亚洲男人的天堂在线观看| 久久久久亚洲AV成人网人人软件| 亚洲午夜免费视频| 久久久久久亚洲精品无码| 亚洲动漫精品无码av天堂| 女人张腿给男人桶视频免费版| 一级做a爱过程免费视|