问题:

下面一个简单的类:

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环境的编译器我没有独立验证过)

转载于:https://www.cnblogs.com/rookieport/archive/2010/05/24/1742780.html

【转】关于eclipse和javac编译结果不一致的问题的分析与解决相关推荐

  1. Eclipse 的常见报错、警告和原因分析、解决方式以及相关操作快捷键小结(持续更新)

    文章目录 前言 一.常见的三种类型错误 二.运行时错误 总结 前言 Eclipse 作为我们开发中最为常用的一款 IDE,功能齐全(虽然近几年被 IDEA 占尽了风头),但是最为基本的一些操作我们是要 ...

  2. SAP中外协加工收货与反冲消耗数量不一致的产生原因分析和解决案例二

    笔者之前写过一篇博客梳理了一个如下主题的案例 SAP中外协加工收货与反冲消耗数量不一致的产生原因分析和解决案例https://blog.csdn.net/lj663/article/details/1 ...

  3. ftl页面中html飘红,eclipse下不能编译.ftl文件,会报错的解决方法

    摘要:1.先安装一个插件右击ftl文件,选择open with 但是没有freeMarker这个选项,如果有直接打开,如果没有则需要下载相关插件. 要安装一个freemarker的插件,才可以编辑FT ...

  4. java编译时为什么总找不到文件,javac编译时找不到文件的问题和运行项目找不到指定类问题...

    问题描述: 刚刚安装完JDK,打开Eclipse创建一个新项目,写了一个测试类进行输出打印语句时,报无法找到相应类. 然后,我跑到CMD中进行javac Test.java运行测试时,报找不到对应文件 ...

  5. javac 编译与 JIT 编译

    javac 编译与 JIT 编译 编译过程 不论是物理机还是虚拟机,大部分的程序代码从开始编译到最终转化成物理机的目标代码或虚拟机能执行的指令集之前,都会按照如下图所示的各个步骤进行: 其中绿色的模块 ...

  6. 66.javac 编译与 JIT 编译\编译过程\javac 编译\词法、语法分析\填充符号表\语义分析\字节码生成\JIT 编译

    66.javac 编译与 JIT 编译 66.1.编译过程 66.2.javac 编译 66.2.1.词法.语法分析 66.2.2.填充符号表 66.2.3.语义分析 66.2.4.字节码生成 66. ...

  7. 第二章 Javac编译原理

    注:本文主要记录自<深入分析java web技术内幕>"第四章 javac编译原理" 1.javac作用 将*.java源代码文件转化为*.class文件 2.编译流程 ...

  8. 【深入Java虚拟机】之七:Javac编译与JIT编译

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/18009455 编译过程 不论是物理机还是虚拟机,大部分的程序代码从开始编译到最终转化成物理 ...

  9. JVM基本概念,Java编译方式,Javac编译的过程

    JDK.JRE.JVM之间的关系 JVM是Java 程序的运行环境,它包括class类加载器.JIT动态编译器.执行引擎.以及垃圾收集器等,它可以将java程序生成的字节码文件解释成具体系统平台上的机 ...

最新文章

  1. 八百客与51CTO结了梁子?
  2. 大数据产品不仅仅是IT工具
  3. 网络摄像机如何与路由器连接方法
  4. SHELL编程实现批量Netatalk字符集文件名替换
  5. hibernate 数据源配置文件
  6. java控制系统音量_Java 控制 Windows 系统音量-Go语言中文社区
  7. 自营型电商和平台型电商的行业秘密是什么?
  8. django中URL常用配置方法
  9. 计算机网络安全与防护第三版课后答案,网络安全与防护—笔试题答案
  10. window下从python开始安装科学计算环境
  11. unable to connect to ssl://gateway.sandbox.push.apple.com:2195 错误
  12. android 清理大师 编程,清理大师 Android v2.3.3
  13. 计算机控制系统第二章答案,计算机控制技术(第2版)部分课后题答案
  14. Swift学习几天就会写项目
  15. 福昕阅读器不能完全显示整个页面的解决办法
  16. Oracle LOB 详解
  17. Yapi 可视化接口管理平台部署文档
  18. 数字三角形的多种解法思路
  19. Roxe:大涨时毅然销毁99% ROC 专注解决跨境汇款难题
  20. 银行刷题记录(招商银行信用卡中心)

热门文章

  1. Activity之间切换 以及传值
  2. 总结:Oracle快速入门
  3. Java学习之模拟纸牌游戏,List的ArrayList,Map的HashMap,重写Collections类的sort方法对指定类进行通过特定属性排序,输入异常处理等的学习...
  4. Idea打Jar包的坑,工程使用ali druid 等ali组件
  5. 用官方的SSD1306.py 驱动 OLED
  6. 获取今天,昨天,本周,上周,本月,上月时间
  7. redis sentinel 主从切换(failover)解决方案,详细配置
  8. linux下错误的捕获:errno、perror和strerror的使用
  9. Linux下mp3文件的乱码问题
  10. android 配置ADB环境