【问题标题】:How do I get all the Compile Time Errors at once in Java?如何在 Java 中一次获取所有编译时错误?
【发布时间】:2020-08-02 17:27:54
【问题描述】:

我想编译一个 java 文件并将所有错误都列在列表中。到目前为止,我使用的是 java 的内置编译器 API,但它有一些问题。

例如,

//demo.java
class demo
{
    public static void main(String[] args) {
        int array = new int[10]
    }
}

我们可以看到缺少分号并且缺少 [](数组括号)。 但是 Java Compiler API 只会返回

demo.java:4: error: ';' expected
        int array = new int[10]
                               ^
1 error

但应该说缺少[]括号和分号;

有没有其他方法可以编译java文件并返回所有错误?

如果有任何使用 Java Compiler API 的方法,请告诉我。

如果有任何其他外部库或工具编译 java 文件并返回错误状态。 外部库应该:

  • 如果文件没有错误,那么库应该说该文件没有错误。
  • 如果 Java 文件有一些错误,则库应返回错误列表及其行号和错误消息。

我搜索了很多关于这个网站的信息。但只找到了一种解决方案,即 Java 编译器 API。但我也想尝试一些其他工具。

【问题讨论】:

    标签: java java-8


    【解决方案1】:

    Java 编译器不会警告您“缺少[]”,因为这不是 Java 编译器可能发出的错误;如果你修复了这段代码中缺少的分号(这是一个语法错误),那么报告的错误是:

    incompatible types: int[] cannot be converted to int
    

    这是一个错误,因为变量的类型被声明为int,但初始化程序的表达式是int[]类型。

    通过将错误描述为“缺少[]”,听起来像是另一个语法错误,但实际上“不兼容类型”错误并不是语法错误;它发生在type-checking 阶段,发生在parsing 之后。但是,如果在解析阶段有任何语法错误,则编译器不会进入类型检查阶段,因为没有有效的解析树进行类型检查。

    所以Java编译器不会在同一个编译单元中同时报告语法错误和类型错误,不管你是使用命令行javac工具还是编译器API。

    【讨论】:

    • 但这可以使用任何外部工具或任何我要问的库来完成吗?
    • @kaya3 这不是它的工作方式。该规范定义了什么是正确程序。所以所有的编译器都应该同意什么是正确的程序,反过来,什么是不正确的,但是在报告错误时,他们进入解释(猜测)作者犯了什么错误的领域。这个报告可能会有很大的不同,在我看来,所有当前的编译器在这方面都失败了。一个原因是他们真的在尝试 OP 想要的东西,当上下文由于先前的错误而不可靠时报告其他错误。
    • 我刚刚检查了这个:ecj(Eclipse 的后端编译器)确实同时报告了缺少分号和类型不匹配,但还报告了第三个错误,“插入 ArrayInitializer 以完成表达式”,它演示问题:我们知道代码与官方语法不匹配,但我们不知道缺少什么,因为这意味着猜测程序员的意图。过去,编译器会在此代码位置显示“}意外”,这也没有帮助。
    • @kaya3 有类似“如果 X 动词 Y 是编译时错误”的语句,但它仍然没有说编译器的错误消息必须是这样的。在某些情况下是这样,但在很多情况下,错误消息的内容仍然不同。正式声明所暗示的只是“X动词Y”不允许在没有错误的情况下编译。如果出现语法错误,您将不会在规范中找到这样的语句。只有一个正式的语法。如前所述,这个问题的具体示例已经允许至少两个(我看到至少三个)不同的错误消息。
    • 出发点是 OP 希望编译器能够同时告知丢失的分号和类型不匹配,并且如前所述,Eclipse 的编译器会执行此操作。加上另一个错误。因此,您声称所有编译器都报告相同的错误是错误的。而这一切都在规范之内。总之,规范要求的是,这个不正确的程序不会被编译,但会产生至少一条错误消息。如果编译器只对每种错误都说“至少有一个错误必须修复”,而没有任何其他细节,那将是完全合法的。细节不是强制性的
    【解决方案2】:

    这是不可能的。 Java 编译器在遇到错误时停止处理源文件。 C/C++ 编译器可以满足您的需求,但大多数以下错误消息具有误导性且无用。

    要获得所有错误的列表,编译器需要使用 AI 技术。编译器需要猜测您的意思。

    【讨论】:

    • 有没有办法使用编译器解析器或语言处理工具?
    • 这是错误的; Java 编译器不会停止处理第一个错误。尝试编译class A { a; b; },你会得到两个语法错误,而不是一个。
    • 是的@kaya3 是对的!编译器在发现任何错误时不会停止
    • 尽管如此,编译理论上发生在“阶段”中,一个阶段中足够严重的错误可能会使下一个阶段的运行毫无意义,因此不可能报告下一个阶段会发现的错误阶段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 2013-06-19
    • 1970-01-01
    • 2017-07-27
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多