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

String是一個很是經常使用的類,應該深刻的去了解Stringjava

如:spa

String str =new String("abc")指針

String str1 = "abc"code

System.out.println(str == str1)對象

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

結果:內存

false字符串

trueget

 

緣由解析:編譯器

  • 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

---------------------------
第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。
的類加載時就完成了初始化,而b要在執行引擎執行到那一行代碼時才完成初始化。
  • 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; //這麼寫則是給引用指向了一個空對象。分配了內存(空對象),因此編譯不會報錯,運行時報空指針異常。

相關文章
相關標籤/搜索