DANCE WITH JAVA

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

          常用鏈接

          統(tǒng)計(jì)

          積分與排名

          好友之家

          最新評(píng)論

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

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

          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
          }

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

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

          評(píng)論

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

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

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

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

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

          有沒有效率提升測(cè)試了才知道..  回復(fù)  更多評(píng)論   

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

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

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

          //--測(cè)試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("平均時(shí)間:"+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;
          }

          }
            回復(fù)  更多評(píng)論   

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

          @a
          先不管你這段代碼寫的如何,邏輯上就有問題,jdk1.5編繹后比jdk1.4運(yùn)行快就一定是因?yàn)榉盒蛦幔?

          就用你這段代碼,不使用泛型的情況下,你用jdk1.4和 jdk1.5分別編繹運(yùn)行一下看到差別了吧。差別不是因?yàn)榉盒停且驗(yàn)閯e的原因。不要只看表面現(xiàn)象,要知到原因。  回復(fù)  更多評(píng)論   

          主站蜘蛛池模板: 华池县| 成安县| 定日县| 胶南市| 西峡县| 延庆县| 乌拉特后旗| 普洱| 玛多县| 达孜县| 拉萨市| 涪陵区| 新田县| 府谷县| 高州市| 启东市| 平定县| 舟曲县| 嘉祥县| 柞水县| 广德县| 嘉义市| 龙里县| 绥棱县| 天柱县| 东乌| 垦利县| 大渡口区| 岳阳县| 静宁县| 平潭县| 隆安县| 茂名市| 仁布县| 天峻县| 祥云县| 广元市| 青海省| 饶平县| 新安县| 淮北市|