为什么编译器不抱怨这个错误?

Moh*_*oud 4 java netbeans

我正在写一些Java问题来帮助我的朋友参加Java考试.我写了一个问题,我假设代码中会出现三个错误,但编译器只抱怨两个.代码是:

class MyClass 
{ 
   static MyClass() 
    {  
     System.out.println("I am The First Statement here!"); 
       this();  
    } 
} 
Run Code Online (Sandbox Code Playgroud)

我预计会出现以下错误:

  1. 构造函数不能是静态的

  2. this 不能在静态函数中(因为构造函数无效)

  3. this 这应该是第一个声明.

NetBeans没有抱怨这里的第二个错误.为什么?

mdm*_*dma 5

当编译器遇到错误时,他们会尝试通过"修复"早期错误来避免所谓的"二次错误" - 由其他错误导致的错误.

例如,由于构造函数声明格式错误,编译器会标记错误.它可以将其解释为构造函数,您尝试创建静态函数,或者作为缺少声明的返回类型的常规静态方法.编译器可以通过忽略static关键字并将其视为常规构造函数来修复您的声明,或者它可以将其视为静态方法并"发明"返回类型以弥补缺少的返回类型.

听起来NetBeans正在采用第一种方法 - 修复构造函数,使其不是静态的.当编译器选择忽略static关键字时,为了避免二次错误,this()调用是有效的,因为编译器发现它在常规构造函数中,因此第二个错误没有被标记.这实际上是理想的行为 - 编译器编写者竭尽全力避免二次错误,因为它们会掩盖"真正的"错误.一旦你自己修复静态构造函数并删除static关键字,this()调用就会有效(除非错误#3.)

总结一下 - 编译器试图向您展示真正的错误,而不是由这些错误引起的所有后续问题.

编辑:发生错误后,编译器尝试通过跳过输入来尝试恢复正常(将标记生成器和解析器重新同步到已知状态).它们跳过的部分可能包含错误,或者导致编译器随后正确解析的错误.因此,错误恢复可能导致一些错误未被报告.从正确性的角度来看,这并不重要 - 只要编译器标记一个错误(导致需要错误恢复的原始错误)就足够了.错误处理和错误报告主要是关于可用性.如果编译器只是在第一个错误处打印"错误"并让你弄清楚错误的位置 - 它就不会非常有用,那么编译器也同样正确.