1. 程式人生 > >關於String str =new String("abc")和 String str = "abc"的比較

關於String str =new String("abc")和 String str = "abc"的比較

string對象 結果 ofo system 內存區域 code false clas 加載

字符串是一個特殊的對象。
字符串一旦初始化就不可以被改變

1. 執行語句String str="abc";時。首先查看字符串池中是否存在字符串"abc",如果存在則直接將“abc”賦給str,如果不存在則先在 字 符串池中新建一個字符串"abc",然後再將其賦給str.


2. 執行語句String str = new String("abc");時。不管字符串池中是否存在字符串“abc”,直接新建一個字符串“abc”,(註意,新建的字符串“abc”不是在字符串池中), 然後將其賦給str。由此可見 1.的效率要高於2的效率。

3. String str1="java";//指向字符串池
  String str2="blog";//指向字符串池
String s = str1+str2;

  +運算符會在堆中建立起兩個String對象,這兩個對象的值分別是“java”,"blog",也就是說從字符串常量池中復制這兩個值,然後再堆中創建兩個對象。然後再建立對象s,然後將“javablog”的堆地址賦給s. 這句話共創建了3個String對象。


System.out.println(s=="javablog");//結果是false;

JVM確實對形如String str="javablog";的對象放在常量池中,但是它是在編譯時name做的。而String s=str1+str2;是在運行時候才能知道的,也就是說str1+str2是在堆裏創建的,所以結果為false了。
String s="java"+"blog";//直接將javablog對象放入字符串池中。 System.out.println(s=="javablog");//結果是true;

String s=str1+"blog";//不放在字符串池中,而是在堆中分分配。 System.out.println(s=="javablog");//結果是false;

總之,創建字符串有兩種方式:兩種內存區域(pool,heap)


1.""創建的字符串在字符串池中。
2.new 創建字符串時,首先查看池中是否有相同的字符串,如果有則拷貝一份放到堆中,然後返回堆中的地址;如果池中沒有則在堆中創建一分,然後返回堆中的地址,
3.在對字符串賦值時,如果右操作數含有一個或一個以上的字符串引用時,則在堆中再建立一個字符串對象,返回引用如:String s= str1+"blog";

之間的區別

第1種:

String a="abc";
String b="abc";
System.out.print(a==b);

結果:true

原因:編譯時,這兩個"abc"被認為是同一個對象保存到了常量池中;運行時JVM則認為這兩個變量賦的是同一個對象,所以返回true。

---------------------
第2種:

String a=new String("abc");
String b=new String("abc");
System.out.print(a==b);

結果:false

原因:用構造器創建的對象,是不會被放入常理池中的,也很明顯這完全是兩個對象,只是內容相同罷了,結果當然為false了。用equals()或者System.out.print(a.intern()==b.intern());就返回true了。

------------------------------
第3種

String a="abc";
String b=new String("abc");
System.out.print(a==b);

結果:false

原因:同上。此外,a的類加載時就完成了初始化,而b要在執行引擎執行到那一行代碼時才完成初始化。


---------------------------
第4種

String a="abcdef";
System.out.print(a=="abcdef");

結果:true

原因:運行出現的字符串常量,若是在常量池中出現過,則JVM會認為同一個對象,以節省內存開銷,所以這兩個字符串會被認為是同一個對象。

-------------------------------------------
第5種

String a="abcdef";
String b="";
String c=a+b;
System.out.print(c=="abcdef");

結果:false

原因:編譯時,先將"abcedf"放在常量池中,而c的值則是在運行時在堆裏創建的。所以為false。


轉載

關於String str =new String("abc")和 String str = "abc"的比較