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

String是一個非常常用的類,應該深入的去了解String

如:

String str =new String(“abc”)

String str1 = “abc”

System.out.println(str == str1)

System.out.println(str.equal(str1))

結果:

false

true

原因解析:

Java運行環境有一個字符串池,由String類維護。
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。
Object o與Object o=null的區別

具體差別如下:
class Test {

public static void main(String[] args) {
Object o1;
o1.toString(); /這裏編譯不能通過,編譯器只認定o1是個引用,沒指向任何對象,所以不能調用方法。/
Object o2 = null;
o2.toString(); /這裏編譯可以過,但是有空指針異常,編譯器認定o2是一個對象,雖然是一個空對象。/
}
}
null對象是一個特殊的對象,他可以是任何類型。他只是作爲一個標記而已,只是爲了標記不存在而存在的。也沒必要去追究他在內存是什麼樣。null就是一個標記而已。容器可以接受一個空對象,但是一個空引用則是不接受的。
Object o; //這種寫法只是分配一個引用,沒有分配內存。
Object o = null; //這麼寫則是給引用指向了一個空對象。分配了內存(空對象),所以編譯不會報錯,運行時報空指針異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章