關(guān)于eclipse和javac編譯結(jié)果不一致的問(wèn)題的分析與解決 (轉(zhuǎn))

          問(wèn)題:

          下面一個(gè)簡(jiǎn)單的類:

          public class MyTest {
           private static String className = String.class.getName(); //紅色部分是下面問(wèn)題的關(guān)鍵
           public static void main(String[] args){
            System.out.println(className);   
           }
          }

          經(jīng)eclipse3.1.1編譯后(指定類兼容性版本為1.4),再反編譯的結(jié)果是:

          public class MyTest
          {

              public MyTest()
              {
              }

              public static void main(String args[])
              {
                  System.out.println(className);
              }

              private static String className;

              static
              {
                  className = java.lang.String.class.getName();
              }
          }

          而經(jīng)過(guò)sun javac(或者ant, antx)編譯后(JDK版本1.4,或者JDK1.5,但是編譯結(jié)果指定版本為1.4),再反編譯的結(jié)果是:

          public class MyTest
          {

              public MyTest()
              {
              }

              public static void main(String args[])
              {
                  System.out.println(className);
              }

              static Class _mthclass$(String x0)
              {
                  return Class.forName(x0);
                  ClassNotFoundException x1;
                  x1;
                  throw (new NoClassDefFoundError()).initCause(x1);
              }

              private static String className;

              static
              {
                  className = (java.lang.String.class).getName();
              }
          }

           

          也就是說(shuō)sun javac編譯出來(lái)的結(jié)果里面多了一個(gè)_mthclass$方法,這個(gè)通常不會(huì)有什么問(wèn)題,不過(guò)在使用hot swap技術(shù)(例如Antx eclipse plugin中的快速部署插件利用hot swap來(lái)實(shí)現(xiàn)類的熱替換,或者某些類序列化的地方,這個(gè)就成為問(wèn)題了。

           

          用_mthclass$在google上搜一把,結(jié)果不多,比較有價(jià)值的是這一篇:http://coding.derkeiler.com/Archive/Java/comp.lang.java.softwaretools/2004-01/0138.html

          按照這個(gè)說(shuō)法,這個(gè)問(wèn)題是由于Sun本身沒(méi)有遵循規(guī)范,而eclipse compiler遵循規(guī)范導(dǎo)致的,而且eclipse compiler是沒(méi)有辦法替換的。

           

          嘗試將JDK版本換成1.5,sun javac生成出來(lái)的_mthclass$是不見了,不過(guò),這回奇怪的是eclipse的編譯結(jié)果中多了一個(gè)成員變量class$0,
          下面是經(jīng)eclipse3.1.1編譯后(指定類兼容性版本為5.0),再反編譯的結(jié)果:
          public class MyTest
          {

              public MyTest()
              {
              }

              public static void main(String args[])
              {
                  System.out.println(className);
              }

              private static String className = java/lang/String.getName();
              static Class class$0;

          }
          而經(jīng)過(guò)sun javac(或者ant, antx)編譯后(JDK版本1.5),再反編譯的結(jié)果是:
          public class MyTest
          {

              public MyTest()
              {
              }

              public static void main(String args[])
              {
                  System.out.println(className);
              }

              private static String className = java/lang/String.getName();

          }

          再在goole上搜了一把,發(fā)現(xiàn)了Eclipse3.2有兩個(gè)比較重要的特征:
          1.與javac的兼容性更好。
          2.提供了單獨(dú)的編譯器,可以在eclipse外部使用,包括ant中使用。

          于是下載eclipse3.2版本,首先驗(yàn)證一下其與sun javac的兼容性如何,
          使用JDK1.4版本的時(shí)候,還是老樣子,sun javac編譯出來(lái)的_mthclass$方法在eclipse3.2的編譯結(jié)果中還是不存在,所以還是不兼容的。
          不過(guò)使用JDK1.5版本的時(shí)候,這會(huì)eclipse 3.2的編譯結(jié)果總算和sun javac一致了。

          雖然,用JDK1.5加上eclipse 3.2已經(jīng)保證了這個(gè)類在兩種編譯器下的兼容性,不過(guò)總覺得不踏實(shí):
          1.誰(shuí)知道這兩個(gè)編譯器還有沒(méi)有其它不兼容的地方呢?
          2.版本要求太嚴(yán)格,很多由于各種原因沒(méi)有使用這些版本的很麻煩。

          因此,還是從根本上解決這個(gè)問(wèn)題比較合適:根本上解決最好就是不要使用兩種不同的編譯器,而使用同一種。
          由于eclipse環(huán)境下的編譯器是不可替換的,所以企圖都使用sun javac的方式不太可行,那么統(tǒng)一使用eclipse自帶的編譯器如何呢?
          剛才提到的eclipse3.2的第二個(gè)比較重要的特性就派上用場(chǎng)了。
          獨(dú)立的eclipse編譯器(1M大小而已)可以在如下地址下載:http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.2-200606291905/ecj.jar
          這個(gè)獨(dú)立的編譯器在antx下的使用也很簡(jiǎn)單:(關(guān)于該編譯器的獨(dú)立使用或者ant下面的使用可以參看this help section: JDT Plug-in Developer Guide>Programmer's Guide>JDT Core>Compiling Java code)
          1.將下載下來(lái)的編譯器放在ANTX_HOME/lib目錄下面。
          2.在總控項(xiàng)目文件的project.xml增加這么一行即可:<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
          這樣就保證了通過(guò)antx打包的類也是用eclipse的編譯器編譯出來(lái)的,當(dāng)然就不應(yīng)該存在類不兼容的情況了。

           

          實(shí)際上,eclipse3.1.1版本也已經(jīng)提供了獨(dú)立的eclipse編譯器,不過(guò)當(dāng)時(shí)并沒(méi)有單獨(dú)提供獨(dú)立的包下載,如果希望使用3.1.1版本的eclipse編譯器,可以使用org.eclipse.jdt.core_3.1.1.jar以及其中包含的jdtCompilerAdapter.jar。(eclipse3.1.1環(huán)境的編譯器我沒(méi)有獨(dú)立驗(yàn)證過(guò))

           


          posted on 2009-05-23 02:15 胡鵬 閱讀(4786) 評(píng)論(0)  編輯  收藏 所屬分類: java基礎(chǔ)

          導(dǎo)航

          <2009年5月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          統(tǒng)計(jì)

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          agile

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 页游| 万载县| 元阳县| 荣昌县| 永宁县| 汽车| 修水县| 长岛县| 乐清市| 呼伦贝尔市| 双流县| 金乡县| 南康市| 内丘县| 金昌市| 临湘市| 绥中县| 三亚市| 大安市| 峡江县| 尚义县| 昌邑市| 裕民县| 金门县| 桂阳县| 临西县| 内黄县| 临湘市| 台东市| 清水河县| 吴旗县| 新竹市| 阜城县| 太原市| 大洼县| 沧源| 惠州市| 郸城县| 高邮市| 安新县| 毕节市|