This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
It won't compile, because the compiler has all the information necessary to determine at compile-time that any object referenced by b is always of the type Bat or a subtype of Bat. It also knows that the types Bat and Bird are not in the same type hierarchy. Therefore no object referenced by b can ever be an instance of Bird.
Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
Piet Souris wrote:Indeed, but why is this considered an error and won't compile?
The error being about unconvertible types.
Simply.... because the Java Language Specification says so. As mentioned, if Java detects that the instanceof comparison always returns false (at compile time), it is an error. Now, as for why the language was designed that way, unfortunately, I don't think there is any documentation of that -- certainly not in the JLS.
Piet Souris wrote:
If you replace the last if by:
then NetBeans gives me two warnings:
braces must be used in if - else constructions
the branche is never used
but it compiles and runs as expected.
First, this is a completely different section of the JLS -- this is discussed in the "unreachable code" section -- so arguably, not sure how it is related.
Anyway, interestingly, the JLS does explain why this works. The "unreachable code" checks are purposely relaxed for "if" conditionals, and the reason for this, is to allow for conditional compilation. You can actually confirm this by changing the "if" to a "while", and it should fail to compile.
This is question from Enthuware . i cant figure out why this code wont compile
For others, who do not have access to the question bank, there is detailed explanation provided with the question ( QID: 2.910 ):
b points to an object of class Bat, which does not extend from Bird. Now, it is possible for b to point to an object of any subclass of Bat. However, it is not possible for that subclass to extend Bird (because a class can at most extend from only one class). Therefore, it is not possible for b to point to an object of a class that extends Bird. The compiler figures out this fact at compile time itself and so the code fails to compile.
Note that there is no compilation issue with b instanceof Flyer because Flyer is an interface and it is possible for b to point to an object of a class that is a sub class of Bat and also implements Flyer. So the compiler doesn't complain. If you make Bat class as final, b instanceof Flyer will not compile because the compiler knows that it is not possible for b to point to an object of a class that implements Flyer.