類似普通對象,通過new創建字符串對象。string str = new string("hello"); 內存圖如下圖所示,系統會先創建一個匿名對象"hello"存入堆內存(我們暫且叫它a),然后new關鍵字會在堆內存中又開辟一塊新的空間,然后把"hello"存進去,并且把地址返回給棧內存中的str, 此時a對象成為了一個垃圾對象,因為它沒有被任何棧中的變量指向,會被gc自動回收。
直接賦值。如string str = "hello"; 首先會去緩沖池中找有沒有一個"hello"對象,如果沒有,則新建一個,并且入池,所以此種賦值有一個好處,下次如果還有string對象也用直接賦值方式定義為“hello”, 則不需要開辟新的堆空間,而仍然指向這個池中的"hello"
解釋
l 字符串的內容是存放在方法區的字符串常量池的,沒有的時候就新建一個,已經存在的時候就直接指過去。
l string str1 = “aa”,這種是直接操作字符串常量池指過去;string str2 = new string(“aa”);這種是先在堆空間開辟這個類的對象,實際上在內部還是指到了字符串常量池;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package two.string.mushroom; public class testtwostring { public static void main(string[] args) { string str1 = "aa" ; string str2 = "aa" ; string str3 = new string( "aa" ); system.out.println( "str1 == str2: " + (str1 == str2)); //它們都指向字符串常量池中的 "aa",true system.out.println( "str1 == str3: " + (str1 == str3)); //它們本身指向不同,false //string類重寫了equals方法,實際上比較的是字符串的內容是否相等,true system.out.println( "str1.equals(str3): " + (str1.equals(str3)) ); animal p1 = new animal( "aa" , 10 ); animal p2 = new animal( "aa" , 12 ); //因為構造器中的方式是直接指向字符串常量池的,所以也是true system.out.println( "p1.name == p2.name: " + (p1.name == p2.name)); } } class animal { string name; int age; animal(string name, int age) { this .name = name; //構造器中的方式是直接指向字符串常量池的 this .age = age; } } |
測試結果
1
2
3
4
|
str1 == str2: true str1 == str3: false str1.equals(str3): true p1.name == p2.name: true |
總結
以上就是本文關于淺談java中string的兩種賦值方式的區別的全部內容,希望對大家有所幫助。
原文鏈接:http://blog.csdn.net/qq_33605778/article/details/55003692