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

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

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

    sharky的點滴積累

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      56 隨筆 :: 104 文章 :: 10 評論 :: 0 Trackbacks

          網上關于String類一些有關問題的討論很多,在這里自我總結一下。希望對剛開始學Java的朋友一對幫助。

    【問題一:字符串的引用比較問題】
    先看個例子,大家預測下結果:
    例1
    package base;

    public class StringTest
    {
        public static void main(String[] args) 
       {
        String A = "test";
        String B = "test";
        String C = new String("test");
        String D = new String("test");
        System.out.println("A==B?" + (A == B));
        System.out.println("C==D?" + (C == D));
        System.out.println("C==A?" + (C == A));
        System.out.println("C equals D?" + (C.equals(D)));

      }
    }

    運行結果:
    A==B? true
    C==D?false
    C==A?false
    C equals D?true

    幾點認識:

    1.引用之間的“=="操作符,表示比較兩邊引用是否相等,即是否指向同一個對象。
    2.對于"String A = "test""這樣建立的字符串對象,如果在下次"String B = "test"",如果內容一樣,JVM就不會在創建新的對象,而是簡單地把新的引用指向已經存在的對象(編譯時)。(即便是在不同的包中)
    3.String.equals(String)是比較字符串的內容。

    理解這幾點,通過分析,很快得出上例結果。
    這里再給出個例子
    例2.

    String s1 = "I love Java";
    String s2 = "I love ";
    String s3 = "Java";
    String s4 = s2 + s3;
    String s5 = "I love "+"Java";

    if (s1 == s4) System.out.println("yes");
    else System.out.println("no");

    if (s1 == s5) System.out.println("yes");
    else System.out.println("no");

    運行結果:
    no
    yes

    分析:s2+s3雖然其內容也是"I love Java",但是s4 的值是運行后出來的,不是編譯的時候。JVM只是把編譯時 "=" 方式創建的 String 對象優化為內容相同時指向相同的對象實體。而當一個字符串由多個字符串常量連接而成時,在編譯期就解析為一個字符串常量。s5就是這樣,自然打出"yes"。
            有的說String+String中的"+"時JVM自動重載的,用于連接字符串,String s1="java"是對"="的重載,重載為創建一個對象,并把對象地址賦給引用。本質是一樣。




    ----------------------------------
    【問題二:Java的參數傳遞問題】
    引出:論壇上一個朋友提出的一道華為的面試題:

    例3:
    package test;

    public class TestString {
    public TestString() {
    }

    public static void main(String[] args) {
    String s=new String("Hello");
    modify(s);
    System.out.println("s = "+s);
    }

    public static void modify(String s)
    {
    s+="world";
    }
    }


    運行結果:
    s = Hello
    為什么是輸出Hello,而不是Helloworld?謝謝

    ------------------------

    首先要確認的幾點認識:
    1.引用不是對象,它沒有屬性和方法,而是指向某一個對象的變量,跟基本數據類型的變量意義一樣。(引用是C中指針的隱藏化)

    例4:
                 String a ="Hello World";
                String b =a;

    分析:a,b是不同的引用變量,但是都是指向同一個對象,即對象"String World"。a,b都是存放了同一個對象的地址,而這個地址指向內存域存放的是"Hello World".

    2.Java中的參數傳遞都是值傳遞,都是拷貝式的,基本數據類型是這樣,不用多說,當傳入的參數是一個對象的引用時,也時值傳遞,只不過傳遞的"值",非對象本身,而是對象雜在內存中的地址。
           所以在例1中:modify(String s)的"s"得到是String s=new String("Hello")中的"s"的引用值拷貝.

    3. String是常量性的,看看JDK文檔里面怎么說String的吧,“Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared”。String的內容是無法改變的,如果需要改變,要考慮用StringBuffer。

    例5:
             1、 String s = "Hello";
             2、 String s1 = s;
             3、 s1 += "World!";

    分析:
          1->2步:s1和s這兩個引用,都指向同一個字符串對象"Hello",此時有2個引用,1個對象
         第3步:   由于String的不可更改性,所以“+=”操作后面操作是:返回一個新的字符串"HelloWorld",并把這個新的字符串的地址給引用s1,而引用s仍然引用原來的"Hello"。
    此時,有2個引用("s","s1"),兩個字符串對象("Hello","HelloWorld")。大家要記?。篠tring的值的改變其實是創建一個新的String對象.
     即:
                s1 += "World!";

               s1 = new String("HelloWold")
    語義上是等價。

    何為語義?   簡單的說就是”你這條語句背后到底讓編譯器做了些什么?“

    這里在提及一個例子
    例6.

    public class Test
    {
      StringBuffer a ;
      public static void main(String[] args)
      {
       Test test = new Test();
       test.a = new StringBuffer("Hello");
       test.test(test.a);
       
       System.out.println("a is "+ test.a);
       
      }
      
      public  void test(StringBuffer strbuf)
      {
       strbuf.append("World");
       System.out.println(strbuf == a);

      }

    運行結果:

    true
    a is HelloWorld

             那這里"strbuf==a",怎么又為true了呢,并且"a is HelloWorld"了,按上面的道理,不是不會修改數據源嗎?注意我們這里運用的是StringBuffer,不同于String,它能修改自己的內容。test方法中傳入的strbuf引用的值為a引用值的拷貝值,但是strbuf.append("World")這句話,是通過引用的值,修改了該值指向對象的內容,a可以調用append修改,strbuf自然也可以。所以,最后打印出a的值是strbuf修改后的對象的值。好比往test方法中傳入的一個可以操作a所指對象的"句柄",可以讓方法里的代碼操作目的對象。

             如果理解上面幾點,理解起來例3為什么是"Hello",我想就比較容易了。
    所以通過這個問題,也告訴我們,在學習語言基礎的時候,不光要讀懂這個語句怎么寫,更應該通過現象看本質,了解語句背后編譯器做了些什么,尤其是內存分配上的操作。雖然Java淡化了內存有關的概念,但是了解更多機制,會幫我對計算機編譯代碼的了解更深一個層次。

    -------------------------------

    相關問題的參考:
    http://www.ideagrace.com/html/doc/2005/09/19/00626.html

    http://www.matrix.org.cn/thread.shtml?forumId=1&topicId=1142&page=1

    http://www.matrix.org.cn/thread.shtml?forumId=1&topicId=27155&page=1

    posted on 2005-10-02 12:17 sharky的點滴積累 閱讀(320) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲精品国产福利一二区| 免费的一级黄色片| 亚洲VA中文字幕不卡无码| 麻豆一区二区三区蜜桃免费| 午夜影视在线免费观看| 伊人久久亚洲综合影院首页| 成人免费毛片内射美女APP| 久久综合久久综合亚洲| 成年18网站免费视频网站| 亚洲av无码成人影院一区| 亚洲av无码成人精品区在线播放 | 最近2018中文字幕免费视频| 亚洲国产情侣一区二区三区| 成人免费无码大片a毛片| 美女无遮挡免费视频网站| 久久久久亚洲av成人无码电影| 你懂的网址免费国产| 亚洲欧洲精品国产区| 免费无码成人AV片在线在线播放| 国产精品亚洲专一区二区三区| 亚洲色精品88色婷婷七月丁香| 一级毛片在线观看免费| 欧洲 亚洲 国产图片综合| 久久久久亚洲精品中文字幕| 无码AV片在线观看免费| 亚洲日韩国产一区二区三区在线| 亚洲国产综合人成综合网站| 日韩内射激情视频在线播放免费| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 亚洲一区中文字幕久久| 最新69国产成人精品免费视频动漫| 一级毛片视频免费观看| 亚洲视频小说图片| 国产乱弄免费视频| 久久久久高潮毛片免费全部播放| 亚洲欧美国产国产综合一区| 一本色道久久综合亚洲精品| 岛国大片免费在线观看| AAA日本高清在线播放免费观看| 一本色道久久88—综合亚洲精品| 色噜噜亚洲精品中文字幕|