【转】关于eclipse和javac编译结果不一致的问题的分析与解决
2010-05-24 14:50
627 查看
问题:
下面一个简单的类:
public class MyTest {
private static String className = String.class.getName(); //红色部分是下面问题的关键
public static void main(String[] args){
System.out.println(className);
}
}
经eclipse3.1.1编译后(指定类兼容性版本为1.4),再反编译的结果是:
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();
}
}
而经过sun javac(或者ant, antx)编译后(JDK版本1.4,或者JDK1.5,但是编译结果指定版本为1.4),再反编译的结果是:
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();
}
}
也就是说sun javac编译出来的结果里面多了一个_mthclass$方法,这个通常不会有什么问题,不过在使用hot swap技术(例如Antx eclipse plugin中的快速部署插件利用hot swap来实现类的热替换,或者某些类序列化的地方,这个就成为问题了。
用_mthclass$在google上搜一把,结果不多,比较有价值的是这一篇:http://coding.derkeiler.com/Archive/Java/comp.lang.java.softwaretools/2004-01/0138.html
按照这个说法,这个问题是由于Sun本身没有遵循规范,而eclipse compiler遵循规范导致的,而且eclipse compiler是没有办法替换的。
尝试将JDK版本换成1.5,sun javac生成出来的_mthclass$是不见了,不过,这回奇怪的是eclipse的编译结果中多了一个成员变量class$0,
下面是经eclipse3.1.1编译后(指定类兼容性版本为5.0),再反编译的结果:
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;
}
而经过sun javac(或者ant, antx)编译后(JDK版本1.5),再反编译的结果是:
public class MyTest
{
public MyTest()
{
}
public static void main(String args[])
{
System.out.println(className);
}
private static String className = java/lang/String.getName();
}
再在goole上搜了一把,发现了Eclipse3.2有两个比较重要的特征:
1.与javac的兼容性更好。
2.提供了单独的编译器,可以在eclipse外部使用,包括ant中使用。
于是下载eclipse3.2版本,首先验证一下其与sun javac的兼容性如何,
使用JDK1.4版本的时候,还是老样子,sun javac编译出来的_mthclass$方法在eclipse3.2的编译结果中还是不存在,所以还是不兼容的。
不过使用JDK1.5版本的时候,这会eclipse 3.2的编译结果总算和sun javac一致了。
虽然,用JDK1.5加上eclipse 3.2已经保证了这个类在两种编译器下的兼容性,不过总觉得不踏实:
1.谁知道这两个编译器还有没有其它不兼容的地方呢?
2.版本要求太严格,很多由于各种原因没有使用这些版本的很麻烦。
因此,还是从根本上解决这个问题比较合适:根本上解决最好就是不要使用两种不同的编译器,而使用同一种。
由于eclipse环境下的编译器是不可替换的,所以企图都使用sun javac的方式不太可行,那么统一使用eclipse自带的编译器如何呢?
刚才提到的eclipse3.2的第二个比较重要的特性就派上用场了。
独立的eclipse编译器(1M大小而已)可以在如下地址下载:http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.2-200606291905/ecj.jar
这个独立的编译器在antx下的使用也很简单:(关于该编译器的独立使用或者ant下面的使用可以参看this help section: JDT Plug-in Developer Guide>Programmer's Guide>JDT Core>Compiling Java code)
1.将下载下来的编译器放在ANTX_HOME/lib目录下面。
2.在总控项目文件的project.xml增加这么一行即可:<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
这样就保证了通过antx打包的类也是用eclipse的编译器编译出来的,当然就不应该存在类不兼容的情况了。
实际上,eclipse3.1.1版本也已经提供了独立的eclipse编译器,不过当时并没有单独提供独立的包下载,如果希望使用3.1.1版本的eclipse编译器,可以使用org.eclipse.jdt.core_3.1.1.jar以及其中包含的jdtCompilerAdapter.jar。(eclipse3.1.1环境的编译器我没有独立验证过)
下面一个简单的类:
public class MyTest {
private static String className = String.class.getName(); //红色部分是下面问题的关键
public static void main(String[] args){
System.out.println(className);
}
}
经eclipse3.1.1编译后(指定类兼容性版本为1.4),再反编译的结果是:
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();
}
}
而经过sun javac(或者ant, antx)编译后(JDK版本1.4,或者JDK1.5,但是编译结果指定版本为1.4),再反编译的结果是:
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();
}
}
也就是说sun javac编译出来的结果里面多了一个_mthclass$方法,这个通常不会有什么问题,不过在使用hot swap技术(例如Antx eclipse plugin中的快速部署插件利用hot swap来实现类的热替换,或者某些类序列化的地方,这个就成为问题了。
用_mthclass$在google上搜一把,结果不多,比较有价值的是这一篇:http://coding.derkeiler.com/Archive/Java/comp.lang.java.softwaretools/2004-01/0138.html
按照这个说法,这个问题是由于Sun本身没有遵循规范,而eclipse compiler遵循规范导致的,而且eclipse compiler是没有办法替换的。
尝试将JDK版本换成1.5,sun javac生成出来的_mthclass$是不见了,不过,这回奇怪的是eclipse的编译结果中多了一个成员变量class$0,
下面是经eclipse3.1.1编译后(指定类兼容性版本为5.0),再反编译的结果:
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;
}
而经过sun javac(或者ant, antx)编译后(JDK版本1.5),再反编译的结果是:
public class MyTest
{
public MyTest()
{
}
public static void main(String args[])
{
System.out.println(className);
}
private static String className = java/lang/String.getName();
}
再在goole上搜了一把,发现了Eclipse3.2有两个比较重要的特征:
1.与javac的兼容性更好。
2.提供了单独的编译器,可以在eclipse外部使用,包括ant中使用。
于是下载eclipse3.2版本,首先验证一下其与sun javac的兼容性如何,
使用JDK1.4版本的时候,还是老样子,sun javac编译出来的_mthclass$方法在eclipse3.2的编译结果中还是不存在,所以还是不兼容的。
不过使用JDK1.5版本的时候,这会eclipse 3.2的编译结果总算和sun javac一致了。
虽然,用JDK1.5加上eclipse 3.2已经保证了这个类在两种编译器下的兼容性,不过总觉得不踏实:
1.谁知道这两个编译器还有没有其它不兼容的地方呢?
2.版本要求太严格,很多由于各种原因没有使用这些版本的很麻烦。
因此,还是从根本上解决这个问题比较合适:根本上解决最好就是不要使用两种不同的编译器,而使用同一种。
由于eclipse环境下的编译器是不可替换的,所以企图都使用sun javac的方式不太可行,那么统一使用eclipse自带的编译器如何呢?
刚才提到的eclipse3.2的第二个比较重要的特性就派上用场了。
独立的eclipse编译器(1M大小而已)可以在如下地址下载:http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.2-200606291905/ecj.jar
这个独立的编译器在antx下的使用也很简单:(关于该编译器的独立使用或者ant下面的使用可以参看this help section: JDT Plug-in Developer Guide>Programmer's Guide>JDT Core>Compiling Java code)
1.将下载下来的编译器放在ANTX_HOME/lib目录下面。
2.在总控项目文件的project.xml增加这么一行即可:<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
这样就保证了通过antx打包的类也是用eclipse的编译器编译出来的,当然就不应该存在类不兼容的情况了。
实际上,eclipse3.1.1版本也已经提供了独立的eclipse编译器,不过当时并没有单独提供独立的包下载,如果希望使用3.1.1版本的eclipse编译器,可以使用org.eclipse.jdt.core_3.1.1.jar以及其中包含的jdtCompilerAdapter.jar。(eclipse3.1.1环境的编译器我没有独立验证过)
![](http://img.doubao.com/public/images/doubao_v1/760-80.gif)
相关文章推荐
- 关于eclipse和javac编译结果不一致的问题的分析与解决 (转)
- 关于eclipse和javac编译结果不一致的问题的分析与解决
- 关于eclipse不编译项目的问题解决
- cocos2d 关于Eclipse 提示 :please define NDK_ROOT的问题(解决Eclipse不会自动编译CPP的问题)
- javac编译servlet类出现的一系列问题及分析解决(javac编译servlet找不到javax.servlet.*包的问题)
- 解决关于sipdroid导入eclipse后编译完成,发布的apk安装之后出现音频解码器出现问题的情况!
- Eclipse中编译和运行时使用的JDK和JRE级别问题(关于"Bad version number in .class file"的异常解决)
- java、javac -version不一致(java编译及运行环境不一致)的环境变量设置问题解决
- 关于eclipse不编译项目的问题解决
- 解决关于Eclipse打包jar包后 运行结果错误的问题
- 关于Android Studio加载第三方jar包无法编译的问题解决。
- 解决eclipse编译 js文件速度太慢的问题
- 使用eclipse编译qt程序遇到问题的解决方法
- 解决 Eclipse 下使用 Ant 编译出现问题: 警告:编码 GBK 的不可映射字符
- Android 关于“NetworkOnMainThreadException”问题的原因分析及解决办法
- 关于IOS应用签名不一致的问题解决方法
- 文《关于c++与java中文乱码问题分析与解决》中一个bug分析
- 关于AFNetWorking 2.5.4之后版本编译报错问题解决方案
- 关于Eclipse和IDEA使用快捷键格式化代码不起作用问题解决
- 关于Android Studio加载第三方jar包无法编译的问题解决。