String a=“aa”;
String不是基本的資料型,而是引用型,以上簡單的一句話再Java編譯器看來再編譯階段是可以決定下來的,那就把「aa」物件存放在目前class檔案的常數池區域(注意不是堆,具體來說是Perm區),常量池同樣也是可以再運作時擴充的,例如「XXX」.intern()的調用,就是執行時期在class的常數池中註入數據,不斷注入可以導致java.lang.OutofMemory:PermGen space異常。流程大概是先拿這個字串與常數池中得每個字串進行equels比較,如果存在一致的則傳回常數池的引用,如果都不存在再注入常數值並傳回目前位址,可見String.intern( )的效率並不高。
private static void test1(){ String a = “a” + “b” +1; Stirng b = “ab1”; System.out.println(a==b); }
顯然回傳結果為True
關於」==「:對於基礎資料型別來說==是比較基本資料型別的值如(byte,short,int,float,char ,double,long,boolean),而對於引用類型,比較的是兩個引用物件的邏輯位址
#關於equels和hashcode():Object類別的equels方法預設就是比較的兩個物件所引用的邏輯位址(return (this == obj);),equels的設計就是要子類別來自己實現比較兩個相同的子類別(對於不同的子類別來比較是沒有任何意義的,所以看到很多equels的實作中都是先判斷兩個物件是不是屬於一個類別)物件是否是相等的,這裡不是引用的位址是否相等。 java預設的hashcode方法提供了物件的hash值,他是一個native方法(native的方法呼叫成本還是很高的),他的回傳值與System.identifyHashCode(Object)方法的回傳值一致,通常情況下是對象頭部的一部分二進位組成的數字,hashcode方法可以說是標識對象,用以再hash演算法中將物件散列開。 String類別重寫了HashCode方法,需要遍歷char[]的所有的char來產生對應的String類別的hashcode,物件其實equels方法和hashcode本身並沒有什麼關係,只是一些類別的使用上導致了大家認為重寫equels()方法就一定要重寫hashcode()方法。如HashMap(還有HashSet,但是HashSet是使用HashMap來實現的),HashMap中put一個元素的過程是先呼叫key的hashcode方法,根據這個方法的回傳值和HashMap中Entity數組的長度計算出Entity的index ,如果這個index上已經有了元素的話在呼叫key的equels方法進行比較,如果存在想通的就替換,如果不存在就插入鍊錶。
關於編譯時優化:對於編譯器來說編譯時優化秉承的原則就是能確定的就優化(例如final),確定不了的就不處理,對於final類型的變量進行優化,對於方法呼叫不進行最佳化,注意String a=“a” + “b”是在編譯時最佳化為a=“ab",而String a=“a” String b=a+”b”在編譯時最佳化為Stringbuffer的拼接
以上是解讀java中的String類的詳細內容。更多資訊請關注PHP中文網其他相關文章!