String
最近學習發現了一個有意思的東西,就記錄下來了,以便自己后面復習,
就是String類的不同創建方式所創建的字串是否相等??以及不同操作所創建的相同字串是不是相等,關于這個問題我也是做了很多嘗試,接下來我們一步步看:
首先
String 無非兩種創建方式:
String str =“aa”;
String str1=new String(“bbb”);
我們還要知道一個 字串是不可變的 這個很重要,一旦創建就不可在修改,文章后面會用到,
這兩種創建方式有何區別?
我們先看最簡單的一種例子:

答案很顯然 :false true,
首先我們要知道Java中具有一個字串常量池,在我們用str1=“AADD"創建字串時,會首先在字串常量池中尋找有沒有這個字串,如果有的話就直接參考這個已存在的字串,如果沒有則會在池中創建,然后參考這個剛創建的字串,這也是我們看到的(str1==str3)為什么會是true的原因,str1已經創建了“AADD”,這時str3在取創建的時候,就直接也參考了同一個字串,他們存放的是相同的參考,值也就相同了,
當使用 new 關鍵字創建字串時,實質上是在堆中創建了一個字串物件”AADD"(注意此時這個物件和str1創建的不是同一個),而str3存放的則是“AADD”在堆中的參考,自然和str1存放的池中的參考截然不同,也就不相等了,
接下來:看這段代碼:

結果: false true
這個做出來,相信你前面已經明白了, str1的操作其實相當于我們第一種創建方式,常量池中沒有就直接在池中創建“justso so”,
代碼執行到str2這一行 和第一個圖是一樣的,一個在堆一個在池中,自然不一樣,
接著 到了str3這一行,此時str3在常量池中找到了“justso so"就不重新在池中創建了,直接參考str1創建好的的物件,兩個的參考是同一個,自然結果是true,
我們也可以通過看地址值的方式:(System.identityHashCode()是一個可以查看hash地址的方法)
這是取消注釋后的結果 我們可以清楚的看到 str1和str2地址截然不同,str3與str1相同,
str1hashcode:366712642
str2hashcode:1829164700
false
str1hashcode:366712642
str3hashcode:366712642
true
**接下來 重點到了:**上圖:

結果: 是個 false,
輸出地址:
str3 hashcode:366712642
str4 hashcode:1829164700
最后才明白,是因為字串不可變性,

我們可以看到String類中采用保存字串的方式是一個加了final的陣列,**對于一個final變數,如果是基本資料型別,其數值再初始化后不可再更改,如果是參考資料型別,在對其初始化后,不能再讓其指向另一個物件,**所以實際上也只是新建了一個字串然后將新字串的參考給原先的字串變數 如下:String str="abcde"; str=str+"gf"; System.out.println(str); 結果:abcdegf 即便str看似是做了連接操作:其實前后的地址也不一樣:
String str="abcde";
System.out.println("strhashcode:"+System.identityHashCode(str));
str=str+"gf";
System.out.println("strhashcode:"+System.identityHashCode(str));
System.out.println(str);
結果:
strhashcode:366712642
strhashcode:1829164700
abcdegf
原因是:在作字串常量的+ 操作時 實質上是new 了一個StringBuilder物件(可變字串)呼叫了append()方法進行操作 拼接完成后呼叫toString()方法回傳了一個String物件,而這一系列的操作都是在堆中進行,所以上圖中的str3在進行了(str1+str2)操作后回傳的是一個在堆中的參考,所以會與str4這個在池中創建的物件不相同,
完結 撒花!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/248585.html
標籤:java
上一篇:《追風箏的人》書摘與筆記
下一篇:必看!程式員逃生指南!
