1. 程式人生 > >String str="abc" 與 String str = new String("abc");詳解

String str="abc" 與 String str = new String("abc");詳解

1.java執行環境有一個字串池,由String類維護,執行語句String str="abc"時:

                                                                                                                                       1.首先檢視字串池中是否存在字串"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";

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; //這麼寫則是給引用指向了一個空物件。分配了記憶體(空物件),所以編譯不會報錯,執行時報空指標異常。