隨筆 - 0, 文章 - 11, 評論 - 0, 引用 - 0
          數據加載中……

          new String("value") 與 String string += "value" 的問題

          環境: JDK6.0  Jad1.5.8(Java反編譯工具)

          先看測試代碼與問題:

          public class StringObjectValueStack {
              
              
          /*
               * new String("value") 到底有幾個對象?
               
          */
              
          public void methodString () {
                  String object 
          = new String("value");
              }
              
              
          /*
               * 為什么 String += "line"; 效率低下?
               
          */
              
          public void methodManyString () {
                  String manyObject 
          = "" ;
                  
          for (int index = 0 ; index < 10 ; index ++) {
                      manyObject 
          += "line" ;
                  }
              }
              
              
          /*
               * 為什么要用StringBuffer呢?
               
          */
              
          public void methodStringBuffer () {
                  StringBuffer stringBuffer 
          = new StringBuffer() ;
                  
          for (int index = 0 ; index < 10 ; index ++) {
                      stringBuffer.append(
          "line") ;
                  }
              }
              
              
          /*
               * 為什么要用StringBuilder呢?
               
          */
              
          public void methodStringBuilder () {
                  StringBuilder stringBuilder 
          = new StringBuilder() ;
                  
          for (int index = 0 ; index < 10 ; index ++) {
                      stringBuilder.append(
          "line") ;
                  }
              }
          }


          看反編譯結果:


          public class StringObjectValueStack {

              
          public StringObjectValueStack() {
              
          //    0    0:aload_0         
              
          //    1    1:invokespecial   #8   <Method void Object()>
              
          //    2    4:return          
              }

              
          public void methodString() {
                  String object 
          = new String("value");
              
          //    0    0:new             #15  <Class String>   創建了一個實例對象 new String()
              
          //    1    3:dup             
              
          //    2    4:ldc1            #17  <String "value"> 創建了第二個實例對象
              
          //    上面的 “value” 雙引號的字符常量 第一次創建在 <字符常量緩沖區(Data Segment)> 中
              
          //    下次再發現調用 "value" , 直接去 Data Segment 中拿值 , 不再新建
              
          //    3    6:invokespecial   #19  <Method void String(String)>
              
          //    4    9:astore_1        
              
          //    5   10:return    
              
          //    至此共創建了兩個對象 
              }

              
          public void methodManyString() {
                  String manyObject 
          = "";
              
          //    0    0:ldc1            #25  <String "">
              
          //    1    2:astore_1        
                  for(int index = 0; index < 10; index++)
              
          //*   2    3:iconst_0        
              
          //*   3    4:istore_2        
              
          //*   4    5:goto            31
                      manyObject = (new StringBuilder(String.valueOf(manyObject))).append("line").toString();
              
          //    5    8:new             #27  <Class StringBuilder> 在 循環體內 創建StringBuilder對象
              
          //    雖然代碼為 String += "line" ; 但編譯器實際創建的還是StringBuilder對象來處理字符串
              
          //    注意 JDK1.4 版本以前,編譯器 實際調用的是StringBuffer, 直到 JDK1.5以后,底層用StringBuilder代替
              
          //    6   11:dup             
              
          //    7   12:aload_1         
              
          //    8   13:invokestatic    #29  <Method String String.valueOf(Object)>
              
          //    9   16:invokespecial   #33  <Method void StringBuilder(String)>
              
          //   10   19:ldc1            #34  <String "line"> 
              
          // 如果 <字符常量緩沖區(Data Segment)> 沒有 "line" 的串對象,則創建了一個對象,以后每循環一次重復使用,不再新建
              
          //   11   21:invokevirtual   #36  <Method StringBuilder StringBuilder.append(String)>
              
          //   12   24:invokevirtual   #40  <Method String StringBuilder.toString()>
              
          //   13   27:astore_1        

              
          //   14   28:iinc            2  1
              
          //   15   31:iload_2         
              
          //   16   32:bipush          10
              
          //   17   34:icmplt          8
              
          //   18   37:return   
              
          //   至此,使用 String string += "line" ; 在循環體中,循環多少次,就創建多少個全新的StringBuilder對象
              }

              
          public void methodStringBuffer() {
                  StringBuffer stringBuffer 
          = new StringBuffer();
              
          //    0    0:new             #48  <Class StringBuffer> 新建 StringBuffer 對象
              
          //    1    3:dup             
              
          //    2    4:invokespecial   #50  <Method void StringBuffer()>
              
          //    3    7:astore_1        
                  for(int index = 0; index < 10; index++)
              
          //*   4    8:iconst_0        
              
          //*   5    9:istore_2        
              
          //*   6   10:goto            23
                      stringBuffer.append("line"); // 只是調用 StringBuffer 的 append 方法 壘加 字符串 并未創建新對象
              
          //    7   13:aload_1         
              
          //    8   14:ldc1            #34  <String "line">
              
          // 如果 <字符常量緩沖區(Data Segment)> 沒有 "line" 的串對象,則創建了一個對象,以后每循環一次重復使用,不再新建
              
          //    9   16:invokevirtual   #51  <Method StringBuffer StringBuffer.append(String)>
              
          //   10   19:pop             

              
          //   11   20:iinc            2  1
              
          //   12   23:iload_2         
              
          //   13   24:bipush          10
              
          //   14   26:icmplt          13
              
          //   15   29:return          
              
          //   至次,只創建了一個StringBuffer對象
              }

              
          public void methodStringBuilder() {
                  StringBuilder stringBuilder 
          = new StringBuilder();
              
          //    0    0:new             #27  <Class StringBuilder>  新建 StringBuilder 對象
              
          //    1    3:dup             
              
          //    2    4:invokespecial   #57  <Method void StringBuilder()>
              
          //    3    7:astore_1        
                  for(int index = 0; index < 10; index++)
              
          //*   4    8:iconst_0        
              
          //*   5    9:istore_2        
              
          //*   6   10:goto            23
                      stringBuilder.append("line"); // 只是調用 StringBuilder 的 append 方法 壘加 字符串 并未創建新對象
              
          //    7   13:aload_1         
              
          //    8   14:ldc1            #34  <String "line">
              
          // 如果 <字符常量緩沖區(Data Segment)> 沒有 "line" 的串對象,則創建了一個對象,以后每循環一次重復使用,不再新建
              
          //    9   16:invokevirtual   #36  <Method StringBuilder StringBuilder.append(String)>
              
          //   10   19:pop             

              
          //   11   20:iinc            2  1
              
          //   12   23:iload_2         
              
          //   13   24:bipush          10
              
          //   14   26:icmplt          13
              
          //   15   29:return      
             
          //   至次,只創建了一個StringBuilder對象
              }
          }

          posted on 2014-05-13 16:52 00001000 閱讀(215) 評論(0)  編輯  收藏 所屬分類: Java 語言基礎

          主站蜘蛛池模板: 资溪县| 南川市| 临泽县| 文水县| 余江县| 壤塘县| 东辽县| 邵阳县| 宿松县| 滨州市| 桂东县| 湘潭市| 汝南县| 漠河县| 高碑店市| 茂名市| 宜阳县| 东莞市| 南昌市| 灵武市| 海南省| 万载县| 正宁县| 泰安市| 特克斯县| 冷水江市| 宝丰县| 德江县| 承德市| 桑植县| 江华| 淄博市| 重庆市| 丰镇市| 锦屏县| 榆林市| 科技| 花莲市| 景宁| 区。| 当雄县|