Why does the compiler not complain about this error?

I am writing some Java questions to help my friends in the Java exam. I wrote a question, and I assumed that there would be three errors in the code, but the compiler only complained about two. The code:

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

I was expecting the following errors:

  • constructor cannot be static

  • this cannot be in a static function (since the constructor is invalid)

  • this should be the first statement here.

NetBeans does not complain about the second error. Why?

+4
source share
4 answers

When compilers encounter errors, they try to avoid the so-called "secondary errors" - errors arising from other errors by "fixing" earlier errors.

For example, the compiler throws an error due to a declared constructor declaration. It can interpret this as a constructor that you tried to make static, or as a regular static method, in which there is no declared return type. The compiler can commit your declaration by ignoring the static keyword and treating it as a regular constructor, or it can consider it as a static method and β€œinvent” a return type to make up for the missing return type.

NetBeans seems to be taking the first approach - fixing your constructor so that it is not static. When the compiler prefers to ignore the static keyword in order to avoid secondary errors, this call () is then valid, since the compiler sees that it is in the regular constructor, so the second error is not flagged. This is a really desirable behavior - the compiler authors go to great lengths to avoid secondary errors, since they are clouds of "real" errors. As soon as you fix the static constructor yourself and delete the static keyword, then this () call will be valid (prohibition of error No. 3.)

To summarize - the compiler is trying to show you real errors, not all subsequent problems caused by these errors.

EDIT: after an error, the compiler tries to recover by skipping the input to try to return to the track (to re-synchronize the tokenizer and analyzer with a known state). The part they skip may contain errors or cause an error in what the compiler subsequently correctly parses. Therefore, error recovery may lead to some error messages. This is not important from the point of view of correctness - as long as the compiler puts one error (the original one, which requires the necessary error recovery), sufficient. Error handling and error reporting is primarily about usability. The compiler would be equally correct if it just printed an β€œerror” on the first error and left you to find out where the error is β€” it just won't be very useful.

+5
source

If I try this in IntelliJ, it will give me the following messages:

  • Compilation completed with 2 errors and 0 warnings
  • (3, 11) static modifier is not allowed here
  • (6, 12) calling this should be the first statement in the constructor
0
source

logically you are right, there are 3 errors in the code. However, the compiler compiles the code sequentially. If previous errors have not disappeared, he will not analyze deeper.

0
source

You must disable compiler tuning in time. This is a compile time error. They should be shown.

Did you try to run?

-2
source

Source: https://habr.com/ru/post/1310664/


All Articles