java常量池概念 詳解及用途

來源:互聯網
上載者:User

標籤:java   常量池   概念   詳解   用途   

在class檔案中,“常量池”是最複雜也最值得關注的內容。

  Java是一種動態串連的語言,常量池的作用非常重要,常量池中除了包含代碼中所定義的各種基本類型(如int、long等等)和對象型(如String及數組)的常量值還,還包含一些以文本形式出現的符號引用,比如:

  類和介面的全限定名;

  欄位的名稱和描述符;

  方法和名稱和描述符。

  在C語言中,如果一個程式要調用其它庫中的函數,在串連時,該函數在庫中的位置(即相對於庫檔案開頭的位移量)會被寫在程式中,在運行時,直接去這個地址調用函數;

  而在Java語言中不是這樣,一切都是動態。編譯時間,如果發現對其它類方法的調用或者對其它類欄位的引用的話,記錄進class檔案中的,只能是一個文本形式的符號引用,在串連過程中,虛擬機器根據這個文本資訊去尋找對應的方法或欄位。

  所以,與Java語言中的所謂“常量”不同,class檔案中的“常量”內容很非富,這些常量集中在class中的一個地區存放,一個緊接著一個,這裡就稱為“常量池”。

java中的常量池技術,是為了方便快捷地建立某些對象而出現的,當需要一個對象時,就可以從池中取一個出來(如果池中沒有則建立一個),則在需要重複重複建立相等變數時節省了很多時間。常量池其實也就是一個記憶體空間,不同於使用new關鍵字建立的對象所在的堆空間。本文只從java使用者的角度來探討java常量池技術,並不涉及常量池的原理及實現方法。個人認為,如果是真的專註java,就必須對這些細節方面有一定的瞭解。但知道它的原理和具體的實現方法則不是必須的。

常量池中對象和堆中的對象

[java] view plaincopy
  1. public class Test{  
  2.   
  3. Integer i1=new Integer(1);  
  4.    Integer i2=new Integer(1);  
  5. //i1,i2分別位於堆中不同的記憶體空間  
  6.   
  7.    System.out.println(i1==i2);//輸出false  
  8.   
  9.   
  10.    Integer i3=1;  
  11.    Integer i4=1;  
  12. //i3,i4指向常量池中同一個記憶體空間  
  13.   
  14.    System.out.println(i3==i4);//輸出true  
  15.   
  16. //很顯然,i1,i3位於不同的記憶體空間  
  17.   
  18. System.out.println(i1==i3);//輸出false  
  19.   
  20. }  
8種基本類型的封裝類和對象池

java中基本類型的封裝類的大部分都實現了常量池技術,這些類是Byte,Short,Integer,Long,Character,Boolean,另外兩種浮點數類型的封裝類則沒有實現。另外Byte,Short,Integer,Long,Character這5種整型的封裝類也只是在對應值小於等於127時才可使用對象池,也即對象不負責建立和管理大於127的這些類的對象。以下是一些對應的測試代碼:

[java] view plaincopy
  1. public class Test{  
  2.   
  3. public static void main(String[] args){  
  4.   
  5.    //5種整形的封裝類Byte,Short,Integer,Long,Character的對象,  
  6.   
  7.    //在值小於127時可以使用常量池  
  8.   
  9.    Integer i1=127;  
  10.   
  11.    Integer i2=127;  
  12.   
  13.    System.out.println(i1==i2)//輸出true  
  14.   
  15.    //值大於127時,不會從常量池中取對象  
  16.   
  17.    Integer i3=128;  
  18.   
  19.    Integer i4=128;  
  20.   
  21.    System.out.println(i3==i4)//輸出false  
  22.   
  23.    //Boolean類也實現了常量池技術  
  24.   
  25.    Boolean bool1=true;  
  26.   
  27.    Boolean bool2=true;  
  28.   
  29.    System.out.println(bool1==bool2);//輸出true  
  30.   
  31.    //浮點類型的封裝類沒有實現常量池技術  
  32.   
  33.    Double d1=1.0;  
  34.   
  35.    Double d2=1.0;  
  36.   
  37.    System.out.println(d1==d2)//輸出false  
  38.   
  39.    
  40.   
  41. }  
  42.   
  43. }  
String也實現了常量池技術

String類也是java中用得多的類,同樣為了建立String對象的方便,也實現了常量池的技術,測試代碼如下:

[java] view plaincopy
  1. public class Test{  
  2.   
  3. public static void main(String[] args){  
  4.   
  5. //s1,s2分別位於堆中不同空間  
  6.   
  7. String s1=new String("hello");  
  8.   
  9. String s2=new String("hello");  
  10.   
  11. System.out.println(s1==s2)//輸出false  
  12.   
  13. //s3,s4位於池中同一空間  
  14.   
  15. String s3="hello";  
  16.   
  17. String s4="hello";  
  18.   
  19. System.out.println(s3==s4);//輸出true  
  20.   
  21. }  
  22.   
  23. }  
最後

細節決定成敗,寫代碼更是如此。

在JDK5.0之前是不允許直接將基礎資料型別 (Elementary Data Type)的資料直接賦值給其對應地封裝類的,如:Integer i = 5; 

但是在JDK5.0中支援這種寫法,因為編譯器會自動將上面的代碼轉換成如下代碼:Integer i=Integer.valueOf(5);  

這就是Java的裝箱.JDK5.0也提供了自動拆箱. Integer i =5;  int j = i;  

Integer的封裝:

[java] view plaincopy
  1. public static Integer valueOf(int i) {    
  2.     final int offset = 128;    
  3.     if (i >= -128 && i <= 127) { // must cache     
  4.         return IntegerCache.cache[i + offset];    
  5.     }    
  6.       return new Integer(i);    
  7.  }    
  8.     
  9.     
  10. private static class IntegerCache {    
  11.     
  12.         
  13.     
  14. private IntegerCache(){}    
  15. static final Integer cache[] = new Integer[-(-128) + 127 + 1];    
  16.     static {    
  17.         for(int i = 0; i < cache.length; i++)    
  18.         cache[i] = new Integer(i - 128);    
  19.     }    
  20. }    
由於cache[]在IntegerCache類中是靜態數組,也就是只需要初始化一次,即static{......}部分,所以,如果Integer對象初始化時是-128~127的範圍,就不需要再重新定義申請空間,都是同一個對象---在IntegerCache.cache中,這樣可以在一定程度上提高效率。

java常量池概念 詳解及用途

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.