我正在写一些Java问题来帮助我的朋友 Java考试。我写了一个问题,我假设了 代码中会出现三个错误,但编译器会发生错误 只抱怨两个。代码是:
class MyClass
{
static MyClass()
{
System.out.println("I am The First Statement here!");
this();
}
}
我预计会出现以下错误:
构造函数不能是静态的
this
不能在静态函数中(因为构造函数无效)
this
这里应该是第一个
言。
NetBeans并没有抱怨第二个错误。为什么呢?
答案 0 :(得分:5)
当编译器遇到错误时,他们会尝试通过“修复”早期错误来避免所谓的“二次错误” - 由其他错误导致的错误。
例如,由于构造函数声明格式错误,编译器会标记错误。它可以将其解释为构造函数,您尝试创建静态函数,或者作为缺少声明的返回类型的常规静态方法。编译器可以通过忽略static关键字并将其视为常规构造函数来修复您的声明,或者它可以将其视为静态方法并“发明”返回类型以弥补缺少的返回类型。
听起来NetBeans正在采用第一种方法 - 修复构造函数,使其不是静态的。当编译器选择忽略static关键字时,为了避免二次错误,this()调用是有效的,因为编译器发现它在常规构造函数中,因此第二个错误没有被标记。这实际上是理想的行为 - 编译器编写者竭尽全力避免二次错误,因为它们会掩盖“真正的”错误。一旦你自己修复了静态构造函数并删除了static关键字,那么this()调用就会有效(除非错误#3。)
总结一下 - 编译器试图向您展示真正的错误,而不是由这些错误引起的所有后续问题。
编辑:发生错误后,编译器会尝试通过跳过输入来尝试恢复正常(将标记生成器和解析器重新同步到已知状态)。他们跳过的部分可能包含错误,或者导致编译器随后正确解析的错误。因此,错误恢复可能导致一些错误未被报告。从正确性的角度来看,这并不重要 - 只要编译器标记一个错误(导致需要错误恢复的原始错误)就足够了。错误处理和错误报告主要是关于可用性。如果编译器只是在第一个错误处打印“错误”并让你弄清楚错误的位置 - 它就不会非常有用。
答案 1 :(得分:0)
如果我在IntelliJ中尝试这个,它会给我这些消息:
答案 2 :(得分:0)
逻辑上你是对的,代码中有3个错误。但是,编译器以顺序方式编译代码。除非以前的错误消失,否则不会解析得更深。
答案 3 :(得分:-2)
您必须已禁用及时编译器设置。这些是编译时错误。必须出示它们。
你试过跑吗?