84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
是不是定义字符串如果不使用new来初始化的话相同的字符串会被定义成一个引用
闭关修行中......
JVM對於String的存储有一点特殊的地方在于有一块String常量池。 這個常數池裡面存著String物件的引用。
String
String常量池
比如,String s = "abc"会先去String常量池中查找有没有已经存在的引用,如果没有,声明的abc会直接生成一个String对象,并且会在String常量池中存入一個引用指向這個String物件。
String s = "abc"
之後直接宣告的字串同樣也會遵循上面的步驟,所以第二次String s2 = "abc"从String常量池中找到了一個引用指向第一次宣告的字串物件。
String s2 = "abc"
而new String("abc")这样会直接在堆中创建新的对象,不会进入String常量池。要把这样的对象引用放入常量池中就涉及另一个String类的方法intern(),這個方法就是回傳一個String物件的常數池引用。如果這個物件不在常數池中,就會把這個String物件放入常數池中並傳回對應的物件參考。
new String("abc")
intern()
題主第一個截圖的方法str2.intern() == str3.intern()这样使用也会返回true,调用intern()返回的String常量池引用是同一個。
str2.intern() == str3.intern()
true
Java中所有非內建資料型別都是引用。
String s = new String("xx");這種方式會建立一塊記憶體空間,並使引用s指向它。
String s = "xx";這種方式會使引用s指向一塊共享的空間。
使用new的方式建立時str2和str3所指向的不同的記憶體空間,故str2和str3是不相等的。
直接使用字串賦值時str2和str3指向是的相同的記憶體空間,故str2和str3是相等的。
可以使用str2.equals(str3)來比較字串的內容。
一個是在常數池中存儲,一個是在堆中new出新物件
幫助你理解這個過程。 java中有幾個點你可以記住下1.所有的字串都會在常數池生成,對應的是CONSTANT_String_info,不可變。 2.普通的物件幾乎都是在堆中生成(當然也有一些比較特殊的比如Class類的對象可能在方法區生成,這個看不同的虛擬機實現,虛擬機規範並沒有強制)3.= =這個判定的時候,對於引用型,說到底都是比對記憶體位址。
好了,有了上述的觀念。在第一個問題中,String s1 = new String("aaa"); 當你new一個對象,jvm就會在堆上幫你開闢一個對象空間,而s1是存在你的本地變數表的,s1指向這個物件空間(可以暫時理解為s1存著物件空間的位址)。所以你new了兩個,是兩個不同的物件空間。 ==判斷當然不同啦,因為,s1和s2指向不同的空間。
第二個問題,上述第一點,每個字串都只會在常數池中存在一份,所以str2指向這個常數池字串的位址,str3也是指向這個常數池字串的位址。 ==判斷自然是相同的。
JVM對於
String
的存储有一点特殊的地方在于有一块String常量池
。這個常數池裡面存著String物件的引用。
比如,
String s = "abc"
会先去String常量池
中查找有没有已经存在的引用,如果没有,声明的abc会直接生成一个String对象,并且会在String常量池
中存入一個引用指向這個String物件。之後直接宣告的字串同樣也會遵循上面的步驟,所以第二次
String s2 = "abc"
从String常量池
中找到了一個引用指向第一次宣告的字串物件。而
new String("abc")
这样会直接在堆中创建新的对象,不会进入String常量池
。要把这样的对象引用放入常量池中就涉及另一个String类的方法intern()
,這個方法就是回傳一個String物件的常數池引用。如果這個物件不在常數池中,就會把這個String物件放入常數池中並傳回對應的物件參考。題主第一個截圖的方法
str2.intern() == str3.intern()
这样使用也会返回true
,调用intern()
返回的String常量池
引用是同一個。Java中所有非內建資料型別都是引用。
String s = new String("xx");這種方式會建立一塊記憶體空間,並使引用s指向它。
String s = "xx";這種方式會使引用s指向一塊共享的空間。
使用new的方式建立時str2和str3所指向的不同的記憶體空間,故str2和str3是不相等的。
直接使用字串賦值時str2和str3指向是的相同的記憶體空間,故str2和str3是相等的。
可以使用str2.equals(str3)來比較字串的內容。
一個是在常數池中存儲,一個是在堆中new出新物件
幫助你理解這個過程。 java中有幾個點你可以記住下
1.所有的字串都會在常數池生成,對應的是CONSTANT_String_info,不可變。
2.普通的物件幾乎都是在堆中生成(當然也有一些比較特殊的比如Class類的對象可能在方法區生成,這個看不同的虛擬機實現,虛擬機規範並沒有強制)
3.= =這個判定的時候,對於引用型,說到底都是比對記憶體位址。
好了,有了上述的觀念。在第一個問題中,
String s1 = new String("aaa"); 當你new一個對象,jvm就會在堆上幫你開闢一個對象空間,而s1是存在你的本地變數表的,s1指向這個物件空間(可以暫時理解為s1存著物件空間的位址)。所以你new了兩個,是兩個不同的物件空間。 ==判斷當然不同啦,因為,s1和s2指向不同的空間。
第二個問題,上述第一點,每個字串都只會在常數池中存在一份,所以str2指向這個常數池字串的位址,str3也是指向這個常數池字串的位址。 ==判斷自然是相同的。