<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專注安卓開發

      導航

      Java 常量池

      最近在網上看到一些Android的面試題,關于String和Integer常量池的,就總結了一下,暫時先記錄下來,以后說不定能用到

        1 public class JavaBase {  
        2   
        3     public static final String STRING20; // 常量  
        4     public static final String STRING21; // 常量  
        5     static {  
        6         STRING20 = "hello";  
        7         STRING21 = "World";  
        8     }  
        9   
       10     public static void main(String[] args) {  
       11   
       12         Integer mInteger1 = new Integer("3");  
       13         Integer mInteger2 = new Integer("3");  
       14         System.out.println(mInteger1 == mInteger2);// false 創建兩個對象  
       15   
       16         // 對象無法與數值進行比較,所以對象會自動拆箱變成數值在進行比較  
       17         int mInteger3 = new Integer("3");  
       18         Integer mInteger4 = new Integer("3");  
       19         System.out.println(mInteger3 == mInteger4);// true  
       20   
       21         // 首先mInteger6 == (mInteger7+mInteger5),因為+這個操作符不適用于Integer對象,mInteger7  
       22         // 和mInteger5進行自動拆箱操作,進行數值相加,即mInteger6 ==3。然后Integer對象無法與數值進行直接比較,  
       23         // 所以mInteger6自動拆箱轉為int值3,最終轉為3 ==3進行數值比較  
       24         Integer mInteger5 = new Integer(0);  
       25         Integer mInteger6 = new Integer(3);  
       26         Integer mInteger7 = new Integer(3);  
       27         System.out.println(mInteger6 == (mInteger7 + mInteger5));// true 在棧中計算  
       28   
       29         Integer mInteger8 = new Integer(3);  
       30         Integer mInteger9 = 3;  
       31         System.out.println(mInteger8 == mInteger9);// false 一個在棧中一個在堆中  
       32   
       33         Integer mInteger10 = 3;  
       34         Integer mInteger11 = 3;  
       35         System.out.println(mInteger10 == mInteger11);// true 實現了常量池  
       36   
       37         // 除Float和Double以外, 其它六種都實現了常量池,但是它們只在大于等于-128并且小于等于127時才使用常量池。  
       38         Double mDouble0 = 3d;  
       39         Double mDouble1 = 3d;  
       40         System.out.println(mDouble0 == mDouble1);// false 沒有實現常量池,相當于分別new一個  
       41   
       42         Integer mInteger12 = 400;  
       43         Integer mInteger13 = 400;  
       44         System.out.println(mInteger12 == mInteger13);// false大于127則在堆中創建,相當于new一個  
       45   
       46         // Boolean類也實現了常量池技術  
       47         Boolean bool1 = true;  
       48         Boolean bool2 = true;  
       49         System.out.println(bool1 == bool2);// 輸出true  
       50   
       51         Boolean bool3 = true;  
       52         Boolean bool4 = new Boolean(true);  
       53         System.out.println(bool3 == bool4);// 輸出false 一個在常量池中一個在堆中  
       54   
       55         // JVM對于字符串常量的"+"連接優化為連接后的值,"hello" + "World"經編譯器優化后就已經是helloWorld,在編譯期  
       56         // 字符串常量的值就確定下來。而對于字符串引用,由于在字符串的"+"連接中,有字符串引用存在,而引用的值在程序編譯期是無法  
       57         // 確定的,所以string0 +"World"無法被編譯器優化,只有在程序運行期來動態分配并將連接后的新地址賦給string1。  
       58         /** 
       59          * String string2 = "hello" + "World"會查找常量池中時候存在內容為"helloWorld"字符串對象,如存在則 
       60          * 直接讓string2引用該對象, 
       61          */  
       62         String string0 = "hello";  
       63         String string1 = string0 + "World";  
       64         String string2 = "hello" + "World";  
       65         System.out.println(string1 == "helloWorld"); // false  
       66         System.out.println(string2 == "helloWorld"); // true  
       67         System.out.println(string1 == string2); // false  
       68   
       69         /** 
       70          * String str = "hello"創建對象的過程 
       71          *1 首先在常量池中查找是否存在內容為"hello"字符串對象 
       72          *2 如果不存在則在常量池中創建"hello",并讓str引用該對象 
       73          *3 如果存在則直接讓str引用該對象 
       74          * 
       75          *String str = new String("hello")創建實例的過程 
       76          *1 首先在堆中(不是常量池)創建一個指定的對象"hello",并讓str引用指向該對象 
       77          *2 在字符串常量池中查看,是否存在內容為"hello"字符串對象 
       78          *3 若存在,則將new出來的字符串對象與字符串常量池中的對象聯系起來 
       79          *4 若不存在,則在字符串常量池中創建一個內容為"hello"的字符串對象,并將堆中的對象與之聯系起來 
       80          *intern 方法可以返回該字符串在常量池中的對象的引用, 
       81          */  
       82         // string3,string4分別位于堆中不同空間  
       83         String string3 = new String("hello");  
       84         String string4 = new String("hello");  
       85         System.out.println(string3 == string4);// 輸出false  
       86   
       87         // string5,string6位于池中同一空間,常量池  
       88         String string5 = "hello";  
       89         String string6 = "hello";  
       90         System.out.println(string5 == string6);// 輸出true  
       91   
       92         // intern首先檢查字符串常量池中是否有該對象的引用,如果存在,則將這個引用返回給變量,否則將引用加入并返回給變量。  
       93         String string7 = new String("hello");  
       94         String string8 = string7.intern();  
       95         String string9 = "hello";  
       96         System.out.println(string8 == string9);// true  
       97   
       98         String string10 = "hello";  
       99         String string11 = new String("hello");  
      100         System.out.println(string10 == string11);// 輸出false 一個在常量池中一個在堆中  
      101   
      102         /** 
      103          * 對于final修飾的變量,它在編譯時被解析為常量值的一個本地拷貝存儲到自己的常量池中或嵌入到它的字節碼流中。 
      104          * 所以此時的string12 + string13和"hello" + "World"效果是一樣的。 
      105          */  
      106         final String STRING12 = "hello";  
      107         final String STRING13 = "World";  
      108         String string14 = STRING12 + STRING13; // 將兩個常量用+連接進行初始化  
      109         String string15 = "helloWorld";  
      110         System.out.println(string14 == string15);// ture  
      111   
      112         String string16 = "hello";  
      113         String string17 = "World";  
      114         String string18 = string16 + string17;  
      115         String string19 = "helloWorld";  
      116         System.out.println(string18 == string19);// false  
      117         System.out.println(string18.intern() == string19);// true  
      118   
      119         /** 
      120          * STRING20和STRING21雖然被定義為常量,但是它們都沒有馬上被賦值。在運算出string22的值之前,他們何時被賦值,以及被賦予什么樣的值, 
      121          * 都是個變數。因此STRING20和STRING21在被賦值之前,性質類似于一個變量。那么string22就不能在編譯期被確定,而只能在運行時被創建了。 
      122          */  
      123   
      124         String string22 = STRING20 + STRING21;  
      125         String string23 = "helloWorld";  
      126         System.out.println(string22 == string23);// false  
      127   
      128         /** 
      129          * string25 == string24當然不相等,string24雖然也是拼接出來的,但new String("lo")這部分不是已知字面量, 
      130          * 是一個不可預料的部分,編譯器不會優化,必須等到運行時才可以確定結果,結合字符串不變定理,所以地址肯定不同。 
      131          */  
      132         String string24 = "Hel" + new String("lo");  
      133         String string25 = "Hello";  
      134         System.out.println(string25 == string24);// false  
      135   
      136         String string26 = "Hello";  
      137         System.out.println(string26 == "Hello");// true  
      138     }  
      139 }  

      在上面我們看到Integer在-128~127之間是使用常量池的,如果不在這個區間就不會使用,其實是重新new了一個Integer,我們看一下源碼

      public static Integer valueOf(int i) {  
          assert IntegerCache.high >= 127;  
          if (i >= IntegerCache.low && i <= IntegerCache.high)  
              return IntegerCache.cache[i + (-IntegerCache.low)];  
          return new Integer(i);  
      }  

      我們看到如果i >= IntegerCache.low && i <= IntegerCache.high就會調用IntegerCache的cache方法,而不會重新new一個integer,繼續,我們找到IntegerCache這個類

       1 private static class IntegerCache {  
       2     static final int low = -128;  
       3     static final int high;  
       4     static final Integer cache[];  
       5   
       6     static {  
       7         // high value may be configured by property  
       8         int h = 127;  
       9         String integerCacheHighPropValue =  
      10             sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");  
      11         if (integerCacheHighPropValue != null) {  
      12             int i = parseInt(integerCacheHighPropValue);  
      13             i = Math.max(i, 127);  
      14             // Maximum array size is Integer.MAX_VALUE  
      15             h = Math.min(i, Integer.MAX_VALUE - (-low) -1);  
      16         }  
      17         high = h;  
      18   
      19         cache = new Integer[(high - low) + 1];  
      20         int j = low;  
      21         for(int k = 0; k < cache.length; k++)  
      22             cache[k] = new Integer(j++);  
      23     }  
      24   
      25     private IntegerCache() {}  
      26 }  

      有一個static的代碼塊,里面初始化了一些Integer,如果范圍在-128~127之間就會從這里面取,如果不在這個范圍內就會new一個Integer。

      final類型如果不賦值是要報錯的,如果這樣賦值沒有報錯

      static {  
        asd="asd";  
      }  
        
      public static final String asd ;  
        
      {  
        qwe="qwe";  
      }  
        
      public final String qwe;  

      再看一下下面的情況

      {  
          qwe=2;  
      }  
        
      public int qwe;  

      如果打應qwe的值是為2,因為斷點調試的時候public int 這行沒有執行。再看一種情況

      {  
          qwe=2;  
      }  
        
      public int qwe=1;  

      如果打印qwe的值為1,因為斷點調試的時候public int這行執行了。同理如果兩個都加上static都一樣

      static {  
          qwe=2;  
      }  
        
      public static int qwe;  

      這個結果也是為2,因為斷點的時候public那行沒有執行,

      static {  
          qwe=2;  
      }  
        
      public static int qwe=1;  

      這種情況就為1了,因為是按照順序執行的。如果一個是static一個不是,又會是上面結果

       {  
          qwe=2;  
      }  
        
      public static int qwe=1;

      這種情況下結果為2,因為static先執行

       {  
          qwe=2;  
      }  
        
      public static int qwe;  

      同理這種情況下也為2,盡管調試的時候public那行沒有執行,因為是static先執行的。

       {  
          qwe=2;  
      }  
        
      public static final int qwe;  

      如果上面這樣寫會報錯的,提示qwe沒有初始化

      static {  
          qwe=2;  
      }  
        
      public static final int qwe;  

      同理上面這個結果也為2,

      static {  
          qwe=2;  
      }  
        
      public static final int qwe=1;  

      那么這種就要報錯了。變量如果沒有賦初值,在調試的時候就不會執行。

      posted on 2018-04-23 21:25  安卓筆記俠  閱讀(408)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 99午夜精品亚洲一区二区| 人妻va精品va欧美va| 色老99久久精品偷偷鲁| 加勒比无码人妻东京热| 东京热一精品无码av| 国产精品久久久久久福利69堂| 国产老女人免费观看黄A∨片| 国产精品免费中文字幕| 插入中文字幕在线一区二区三区 | 亚洲成av人片乱码色午夜| 亚洲精品日韩精品久久| 精品国产一区二区色老头| 国产精品无码无卡在线观看久| 中文字幕无码视频手机免费看| √天堂中文在线最新版| 亚洲欧美综合中文| 国产伦一区二区三区精品| 永久免费av无码网站直播| 欧美视频精品免费覌看| 国产精品一码二码三码四码| 熟女人妻视频| 欧洲人与动牲交α欧美精品| 老色批国产在线观看精品| 免费国产女王调教在线视频| 制服丝袜人妻有码无码中文字幕| 最近中文字幕日韩有码| 春色校园综合人妻av| 国产一区二区三区尤物视频| 久久蜜臀av一区三区| 新河县| 亚洲精品一区二区三区色| 在国产线视频A在线视频| 人妻av无码系列一区二区三区| 久久人人97超碰精品| 日本真人添下面视频免费| 午夜免费视频国产在线| 天堂av最新版中文在线| 欧洲美女黑人粗性暴交视频| 国产精品一区二区三区污| 精品国产美女福到在线不卡| 亚洲精品熟女一区二区|