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

时间:2010-05-23 17:26:51

标签: java netbeans

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

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

我预计会出现以下错误:

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

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

  3. this这里应该是第一个 言。

  4. NetBeans并没有抱怨第二个错误。为什么呢?

4 个答案:

答案 0 :(得分:5)

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

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

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

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

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

答案 1 :(得分:0)

如果我在IntelliJ中尝试这个,它会给我这些消息:

  • 编译完成,包含2个错误和0个警告
  • (3,11)modifier static not allowed here
  • (6,12)对此的调用必须是构造函数
  • 中的第一个语句

答案 2 :(得分:0)

逻辑上你是对的,代码中有3个错误。但是,编译器以顺序方式编译代码。除非以前的错误消失,否则不会解析得更深。

答案 3 :(得分:-2)

您必须已禁用及时编译器设置。这些是编译时错误。必须出示它们。

你试过跑吗?