70

当我尝试使用 javac 编译此类时,出现编译错误并且未创建 Test.class。

public class Test {
    public static void main(String[] args) {
        int x = 1L;  // <- this cannot compile
    }
}

但是当我在 Eclipse 中创建这个类时,我可以看到 Test.class 出现在 target/classes 中。当我尝试使用 java.exe 从命令行运行此类时,我得到

线程“main”java.lang.Error 中的异常:未解决的编译问题:
类型不匹配:无法从 long 转换为 int

Eclipse 是否使用其自己的特殊 Java 编译器来创建损坏的 .class?java.exe 如何知道 .class 中的编译问题?

4

3 回答 3

65

这就是 Java 编译器如何知道类中的编译错误的方式。

public static void main(String[] paramArrayOfString)
{
    throw new Error("Unresolved compilation problem: \n\tType mismatch: cannot convert from long to int.\n");
}

如果你反编译你的类文件,你可以看到编译器生成的类文件的上述main()方法。这是因为 Eclipse 使用的编译器Eclipse Compiler for Java)与标准的 Java 编译器不同!

于 2013-05-06T07:40:24.730 回答
42

Eclipse 使用 IBM 编译器,它可以选择创建不编译的类,将错误替换为

throw new Error();

恕我直言,这是非常糟糕的做法,我已经看到一些质量很差的项目使用它。该项目一次没有完全编译好几个星期。

与试图最小化错误成本的快速失败策略不同,尽可能晚地发现错误也可以最大限度地提高修复它们的成本。

该策略仅在您快速编写原型代码时才有效,即您知道的代码永远不会投入生产。(很难确定会是这样)

于 2013-05-06T07:38:55.000 回答
27

是的,Eclipse使用自己的特殊编译器;被称为“ecj”。来自 Stack Overflow 的问题javac 和 Eclipse 编译器有什么区别?

一个显着的区别是 Eclipse 编译器允许您运行实际上没有正确编译的代码。如果出现错误的代码块从未运行,您的程序将运行良好。否则它将抛出一个异常,表明您尝试运行无法编译的代码。

于 2013-05-06T07:39:35.990 回答