I am writing some Java questions to help my friends in the Java exam. I wrote a question and I assumed that three errors would occur in the code but the compiler only complained about two. The code is:
class MyClass
{
static MyClass()
{
System.out.println("I am The First Statement here!");
this();
}
}
I expected the following errors:
the constructor can't be static
thi开发者_高级运维s
can't be in a static function (since the constructor isn't valid)this
here should be the first statement.
NetBeans isn't complaining about the second error here. Why?
When compilers encounter errors, they try to avoid so-called "secondary errors" - errors resulting from other errors, by "fixing-up" earlier errors.
For example, the compiler flags an error because of the malformed constructor declaration. It can interpret this as either a constructor, that you've tried to make static, or as a regular static method that is missing a declared return type. The compiler can fix up your declaration either by ignoring the static keyword, and treating it as a regular constructor, or it can treat it as a static method and "invent" a return type to make up for a missing return type.
It sounds like NetBeans is taking the first approach - fixing up your constructor so that it is not static. When the compiler chooses to ignore the static keyword, to avoid secondary errors, the this() call is then valid, since the compiler sees that it is in a regular constructor, so the second error is not flagged. This is actually desirable behaviour - compiler writers go to great lengths to avoid secondary errors, since they cloud the "real" errors. As soon as you fix up the static constructor yourself and remove the static keyword, the this() call will then be valid (barring error #3.)
To sum up - it's the compiler trying to show you the real errors, rather than all the subsequent problems caused by those errors.
EDIT: after an error, a compiler tries to recover by skipping over input to try to get back on track (to resync the tokenizer and parser to a known state). The portion they skip may have contained errors, or have caused an error in what the compiler subsequently correctly parses. Thus, error-recovery can lead to some errors not being reported. This is not significant from a correctness perspective - as long as the compiler flags one error (the original one that lead to error-recovery being required) that's sufficient. Error handling and error reporting is primarily about usability. A compiler would be equally correct if it just printed "error" at the first error and left you to figure out where the error is - it just wouldn't be very usable.
If I try this in IntelliJ, it gives me these messages:
- Compilation completed with 2 errors and 0 warnings
- (3, 11) modifier static not allowed here
- (6, 12) call to this must be first statement in constructor
logically you are right, there are 3 errors in the code. However the compiler compiles the code in a sequential way. Unless the previous errors are gone it won't parse any deeper.
You must have disabled the in-time compiler setting. These are the compile time error. They must be shown.
Did you try running?
精彩评论