DANCE WITH JAVA

          開發(fā)出高質(zhì)量的系統(tǒng)

          常用鏈接

          統(tǒng)計

          積分與排名

          好友之家

          最新評論

          再次證明JDK1.5泛型實現(xiàn)原理

          在這篇文章中用Jad說明了JDK1.5中的泛型是擦拭法實現(xiàn),實際是通過編繹前處理,或者編譯器實現(xiàn)的。但有人說Jad還不支持1.5的語法,那么從另一個角度證明一下,就有了這篇文章。

          import ?java.util.ArrayList;


          public ? class ?Generic? {

          ????
          public ? static ? void ?main(String[]?args)? {
          ????????ArrayList?list1?
          = ? new ?ArrayList();
          ????????list1.add(
          " 1 " );
          ????????String?str1?
          = ?(String)list1.get( 0 );
          ????????
          ????????ArrayList
          < String > ?list2? = ? new ?ArrayList < String > ();
          ????????list2.add(
          " 1 " );
          ????????String?str2?
          = ?list2.get( 0 );
          ????}


          }

          取得上邊這段代碼的字節(jié)碼:(如何取得字節(jié)碼見這里)
          //?class?version?49.0?(49)
          //?access?flags?33
          public?class?Generic?{

          ??
          //?compiled?from:?Generic.java

          ??
          //?access?flags?1
          ??public?<init>()V
          ???L0?(
          0)
          ????LINENUMBER?
          4?L0
          ????ALOAD?
          0
          ????INVOKESPECIAL?java
          /lang/Object.<init>()V
          ????RETURN
          ???L1?(
          4)
          ????LOCALVARIABLE?
          this?LGeneric;?L0?L1?0
          ????MAXSTACK?
          =?1
          ????MAXLOCALS?
          =?1

          ??
          //?access?flags?9
          ??public?static?main([Ljava/lang/String;)V
          ???L0?(
          0)
          ????LINENUMBER?
          7?L0
          ????NEW?java
          /util/ArrayList
          ????DUP
          ????INVOKESPECIAL?java
          /util/ArrayList.<init>()V
          ????ASTORE?
          1
          ???L1?(
          5)
          ????LINENUMBER?
          8?L1
          ????ALOAD?
          1
          ????LDC?
          "1"
          ????INVOKEVIRTUAL?java
          /util/ArrayList.add(Ljava/lang/Object;)Z
          ????POP
          ???L2?(
          10)
          ????LINENUMBER?
          9?L2
          ????ALOAD?
          1
          ????ICONST_0
          ????INVOKEVIRTUAL?java
          /util/ArrayList.get(I)Ljava/lang/Object;
          ????CHECKCAST?java
          /lang/String
          ????ASTORE?
          2
          ???L3?(
          16)
          ????LINENUMBER?
          11?L3
          ????NEW?java
          /util/ArrayList
          ????DUP
          ????INVOKESPECIAL?java
          /util/ArrayList.<init>()V
          ????ASTORE?
          3
          ???L4?(
          21)
          ????LINENUMBER?
          12?L4
          ????ALOAD?
          3
          ????LDC?
          "1"
          ????INVOKEVIRTUAL?java
          /util/ArrayList.add(Ljava/lang/Object;)Z
          ????POP
          ???L5?(
          26)
          ????LINENUMBER?
          13?L5
          ????ALOAD?
          3
          ????ICONST_0
          ????INVOKEVIRTUAL?java
          /util/ArrayList.get(I)Ljava/lang/Object;
          ????CHECKCAST?java
          /lang/String
          ????ASTORE?
          4
          ???L6?(
          32)
          ????LINENUMBER?
          14?L6
          ????RETURN
          ???L7?(
          34)
          ????LOCALVARIABLE?args?[Ljava
          /lang/String;?L0?L7?0
          ????LOCALVARIABLE?list1?Ljava
          /util/ArrayList;?L1?L7?1
          ????LOCALVARIABLE?str1?Ljava
          /lang/String;?L3?L7?2
          ????LOCALVARIABLE?list2?Ljava
          /util/ArrayList;?L4?L7?3
          ????
          //?signature?Ljava/util/ArrayList<Ljava/lang/String;>;
          ????
          //?declaration:?java.util.ArrayList<java.lang.String>
          ????LOCALVARIABLE?str2?Ljava/lang/String;?L6?L7?4
          ????MAXSTACK?
          =?2
          ????MAXLOCALS?
          =?5
          }

          仔細看一下,每個代碼塊對應(yīng)的都有
          INVOKEVIRTUAL java/util/ArrayList.get(I)Ljava/lang/Object;
          CHECKCAST java/lang/String
          有沒有泛型的字節(jié)碼是一樣的,說明在運行時,都進行了轉(zhuǎn)型,所以說上一篇文章的說明應(yīng)改是正確的。

          posted on 2006-11-10 13:05 dreamstone 閱讀(3626) 評論(5)  編輯  收藏 所屬分類: jdk相關(guān)

          評論

          # re: 再次證明JDK1.5泛型實現(xiàn)原理 2006-11-13 15:46 Tin

          對,對。就是擦拭法。編譯時大部分元信息被擦拭了,不過繼承和泛型方法的Generic Type還可以在編譯后獲取回來,這就挺夠用了,但是夠Tricky。  回復  更多評論   

          # re: 再次證明JDK1.5泛型實現(xiàn)原理 2006-11-14 01:08 dreamstone

          嗯,不過Java的實現(xiàn)方式導致的一個結(jié)果就是泛型只簡化了代碼,并沒有提高效率。但是dot net利用C++類似的template的方式來實現(xiàn),效率提升很大。  回復  更多評論   

          # re: 再次證明JDK1.5泛型實現(xiàn)原理[未登錄] 2007-03-22 20:25 a

          有沒有效率提升測試了才知道..  回復  更多評論   

          # re: 再次證明JDK1.5泛型實現(xiàn)原理[未登錄] 2007-03-22 20:38 a

          經(jīng)過實際測試發(fā)現(xiàn),JDK1.5泛型 確實比以前效率有所提升

          代碼如下:(這是沒有采用泛型的代碼,采用泛型只要改三個地方然后在測試)
          public static void main(String[] args){

          //--測試JDK1.4 和 JDK5的性能...

          System.out.println(NormMisc.getStDateTime());
          long startime = 0;
          long ttime = 0;
          for(int j=0;j<30;j++){
          startime = System.currentTimeMillis();
          for(int ii=0;ii<5000;ii++){
          ArrayList l = new ArrayList();
          for(int i=0;i<10;i++){
          Car c = new Car();
          c.setDesc("Desc");c.setName("name-"+i);c.setNumber("Number");
          l.add(c);
          }
          for(int i = 0;i<l.size();++i){
          Car c = (Car)l.get(i);
          String cs = c.toString();
          //System.out.println(cs);
          }
          l.clear();
          }
          ttime += (System.currentTimeMillis()-startime);
          }
          System.out.println(NormMisc.getStDateTime());
          System.out.println("平均時間:"+ttime/10);
          }
          }

          class Car{
          private String name;
          private String number;
          private String desc;
          /**
          * @return desc
          */
          public String getDesc() {
          return desc;
          }
          /**
          * @param desc 要設(shè)置的 desc
          */
          public void setDesc(String desc) {
          this.desc = desc;
          }
          /**
          * @return name
          */
          public String getName() {
          return name;
          }
          /**
          * @param name 要設(shè)置的 name
          */
          public void setName(String name) {
          this.name = name;
          }
          /**
          * @return number
          */
          public String getNumber() {
          return number;
          }
          /**
          * @param number 要設(shè)置的 number
          */
          public void setNumber(String number) {
          this.number = number;
          }


          public String toString(){
          return "name "+name+",number "+number+",desc "+desc;
          }

          }
            回復  更多評論   

          # re: 再次證明JDK1.5泛型實現(xiàn)原理 2007-03-23 10:48 dreamstone

          @a
          先不管你這段代碼寫的如何,邏輯上就有問題,jdk1.5編繹后比jdk1.4運行快就一定是因為泛型嗎?

          就用你這段代碼,不使用泛型的情況下,你用jdk1.4和 jdk1.5分別編繹運行一下看到差別了吧。差別不是因為泛型,而是因為別的原因。不要只看表面現(xiàn)象,要知到原因。  回復  更多評論   

          主站蜘蛛池模板: 清远市| 长乐市| 十堰市| 南汇区| 高台县| 娱乐| 霞浦县| 东方市| 临湘市| 宜章县| 宜兴市| 舒城县| 灵石县| 轮台县| 西充县| 乐安县| 苍山县| 海兴县| 安岳县| 清丰县| 怀来县| 弥勒县| 繁峙县| 郯城县| 四川省| 视频| 乌拉特后旗| 临洮县| 平顺县| 葫芦岛市| 遂溪县| 清新县| 蒲江县| 邵阳县| 宜宾县| 确山县| 进贤县| 通化市| 屯门区| 左贡县| 抚州市|