string是在**中非常常見的一種資料型別.它能直接像基本型別一樣直接賦值(string str = "test"),也能像引用型別一樣建立乙個例項(string str = new string("test")),當然毫無疑問string是引用型別.
(1)sring str = "test"; //此種方式會在字串常量池中建立乙個"test'"常量,當有乙個新的變數同樣也賦值為"test"時,這個新的變數也指向了這個"test"常量.
(2)string str = new string("test"); //此種方式會在堆記憶體中new乙個"test"物件例項,詳細分析見下文.
(1)只有使用引號包含文字的方式建立的string物件之間使用"+"連線產生的新物件才會被加入到字串池中。
string str = "hello" + "world"; //這才會在字串池中建立乙個"helloworld"字串,而不是去堆中建立乙個string物件。
(2)對於所有包含new方式建立物件(包括null)的「+」連線表示式,它所產生的新物件都不會被加入字串池中。
string str1 = "hello";string str2 = "world";
string str = str1 + str2; //
此時str產生的"helloworld"並不會在字串池中,而是在堆中建立乙個string物件。
綜上.
tring str1 = "hello";string str2 = "world";
string str3 = "hello" + "world";
string str4 = str1 +str2;
//str3 == str4 ->false,原因見上。str4是在堆中建立的string物件,str3是在字串池中建立的的"helloworld"
但是!以上的情況是一般情況!
special1.這個例子實際仔細一分析也很好理解,str1和str2都是final常量,它們在類編譯時就已經確定。
publicclass
demo
}
special2.這個例子和上個例子不同在於final常量被宣告的時候,並沒有馬上給它賦值。在str4被賦值前str1+str2是何值都還不確定,str1和str2在賦值前實際上就是乙個變數而不是乙個常量,那麼str4就不能在編譯期被確定,而只能在執行時被建立。
publicclass
demo
public
static
void
main(string args)
}
回到開始提到的問題:
string str = new string("test"); //建立了幾個物件?
2個。在類載入時會建立乙個"xyz"物件放到字串常量池中,在執行時會從常量池中賦值乙份到堆中,並且將堆中這個物件的引用交給s1持有。
關於string類的深淺拷貝問題
首先,先看一下下面的 會出現什麼問題?class string else string string const string s data s.data private char data void test 上面的程式會奔潰,讓我們來分析原因 這就是所謂的淺拷貝,也稱位拷貝,編譯器只是直接將指標...
關於String定義賦值的部分問題
string為什麼是不可變的?或者說為什麼string使用final修飾?string字串建立時實際上是建立了乙個不可變的char陣列,指定著唯一的引用位址,當我們對string字串進行修改重新賦值時,我們看到的結果是字串的值改變了,但是對於底層來說,相當於重新new了乙個string,引用位址變了...
關於map中含數字string的排序問題
大家都知道map內部是按照平衡二叉樹來設計的,所以無論是直接寫 如 mapstr map str map alex yes?str map alex no 之後,這個map裡的順序就是 alex no alex yes?當然,這是我之後才頓悟到的.具體問題是這樣,我簡化一下,由於需要在buf裡寫入值...