標籤:機制 傳遞 online 沒有 存在 otn source out 結果
原文地址:http://blog.laofu.online/2017/08/18/String-In-dotnet-Java/Java字串碰到的問題
在寫Java程式碰到一個問題,而正是這個問題引發了我對字串的思考,Java範例程式碼如下:
public void TestStr(String success) { if(success=="Y"){ System.out.println("Equal"); } else { System.out.println("Not Equal"); } }
上面的這個函數很簡單,但會隨著調用的方式的不同而顯示出不同的結果:
public void CallMethod(){ TestStr(“Y”);//Equal TestStr(“YY”.substring(0,1));//Not Equal}
對於這樣的一個結果,我們可以先思考一個問題:” == “ 這個運算子的作用?
對於基礎資料類型而言是比較值是否相同(作用與equal相同)
對於參考型別,則比較地址是否一樣
但如果理解上面的代碼,我們還要理解Java中字串的機制。由於字串是比較常用的類型,為了保證效能,所以在設計字串的時候會有一個“池”的概念。
所以對於上面的代碼,因為在開始已經建立的“Y”字串,所以後面出生現的所有的“Y”都是引用我們當前的"Y",所以我們就可以理解為什麼第一個是列印Equal,另一個是列印Not Equal.
.Net中如何處理
而對於.Net來說,字串的原理大致相同,如果是相同的代碼,但運算的結果是與Java不一樣的:
我們知道在.Net string也是參考型別,但當“==”作用於兩個參考型別的時候,比較則是地址,但在.Net中字元比較時,比較的卻是值。這個歸功於.Net對“==”的重載,string源碼。如果想比較地址,則使用 object.ReferenceEquals()函數。
public static bool operator == (String a, String b){ return String.Equals(a, b);}
對於.Net運算子多載的這個動作,個人覺得更貼近日常的使用習慣,因為在編碼的過程中,字串中絕大多數的使用情境都是值,而不是引用。而對Java而言,保證的運算的原汁原味,少了人為的封裝的幹擾,使用是注意區分,習慣了反而覺得更為合理。
幾個疑問 字串是參考型別,為什麼不使用new來建立對象?
字串是一個特殊的引用對象 ,聲明就是建立了一個對象,如果使用new,則會重複的建立對象(Java中可以使用new建立,.Net中則不允許這樣操作),浪費記憶體,如下:
String str=new String("1234"); String str1="1234";
兩種的定義方式相同,但是使用new的時候,又額外分配了記憶體空間。
字串是參考型別,但是傳參的時候卻無法修改它的值?有其它的參考型別有什麼不同?
public void CallMethod(){ String str="abc"; AddSuffix(str); System.out.println(str);//列印出abc } public void AddSuffix(String x){ x=x+"123"; }
當我們去調用這個函數的時候,發現str的值卻沒有發生改變。 因為在調用AddSuffix 函數時,str把自己作拷貝成一個副本傳遞給形參x,當對x賦值的時候,系統重新建立了一個字元對象,把引用的地址給x,此處是重新建立對象,而不是修改原來的字串對象(字串不可更改)。兩種方式示意如下:
第48篇 說說.Net與Java中的字串