我們再來看一段程式碼:
執行一下:
沒錯,一個true,一個是false,(答錯的小朋友去面壁去),大家可能在想編譯器肯定又調皮了,編譯的時候是不是又偷偷加了些什麼,迫不及待的開啟class檔案看一下:
除了刪掉了空行以外和我的java原始檔一致呀,這回可冤枉編譯器了,那為什麼會導致不同的結果呢?我們都知道,Java程式碼是執行在JVM裡的,那是不是JVM在執行這段程式碼時給我們做了什麼?
在JVM中,當程式碼執行到String s1 = "100" 時,會先看常量池裡有沒有字串剛好是“100”這個物件,如果沒有,在常量池裡建立初始化該物件,並把引用指向它,如下圖,綠色部分為常量池,存在於堆記憶體中。
當執行到String s2 = "100" 時,發現常量池已經有了100這個值,於是不再在常量池中建立這個物件,而是把引用直接指向了該物件,如下圖:
這時候我們列印System.out.println(s1 == s2)時,由於==是判斷兩個物件是否指向同一個引用,所以這兒列印出來的就應該是true。
繼續執行到Strings3 = new String("100") 這時候我們加了一個new關鍵字,這個關鍵字呢就是告訴JVM,你直接在堆記憶體裡給我開闢一塊新的記憶體,如下圖所示:
繼續執行String s4 = new String("100")
這時候再列印System.out.println(s3 == s4) 那一定便是false了,因為s3和s4不是指向對一個引用(物件)。
注:圖中只是畫出了main方法棧和相關物件在記憶體中的大致模擬,實際中JVM中記憶體管理比較複雜,大家有條件的話可以去找《Java虛擬機器規範》這本書去深入研究。
結論:我們在比較兩個String物件內容時,無論是怎麼宣告的,都一定要使用equals去比較,不能用==,在Java中沒有過載操作符這一說,特別是從其它語言轉到Java的童鞋們要注意。equals我會在後續專欄裡已經做了詳細解說。
下一篇:說說Java裡的equals(上) - Java那些事兒
如果喜歡本系列文章,請為我點贊或順手分享,您的支援是我繼續下去的動力,您也可以在評論區留言想了解的內容,有機會本專欄會做講解,最後別忘了關注一下我。
轉載無限歡迎,但請註明「作者」和「原文地址」。轉載請在文中保留此段,感謝您對作者版權的尊重。如需商業轉載或刊登,請聯絡作者獲得授權。