The grammar in chapter 18 of JLS v7 seem to differ from the constructs elsewhere in the documentation, but to me there seem to be differences. Specifically in chapter 15 the rules are:
RelationalExpression:
ShiftExpression
RelationalExpression < ShiftExpression
RelationalExpression > ShiftExpression
RelationalExpression <= ShiftExpression
RelationalExpression >= ShiftExpression
RelationalExpression instanceof ReferenceType
which makes foo instanceof Bar
a RelationalExpression (and therefore an EqualityExpresson) which in turn can be used as LHS in the EqualityExpression rule which makes foo instanceof Bar == false
an EqualityExpression.
But when looking at the grammar in chapter 18 they've simplified it a bit:
Expression2:
Expression3 [Expression2Rest]
Expression2Rest:
{ InfixOp Expression3 }
instanceof Type
Which looks odd, which means that we can chain together Expression3
s with binary operators OR we can check the type of one Expression3
. Specifically now foo instanceof Bar
is an Expression2
, but I don't see that it would be valid to use an Expression2
as LHS of an equality comparision.
Have I missed something in the grammar of chapter 18 that makes foo instanceof Bar == false
a valid expression? Note that it is a valid expression according to the rules in chapter 15 and according to my compiler.
This question deserves a good answer, so let's take a good close look.
Based solely on the grammar in Chapter 18:
Anything with an InfixOp (e.g.
==
) either fits Expression2Rest or fits nothing. And Expression2Rest only belongs inside Expression2. So, iffoo instanceof Bar == false
is legal Java, that means thatfoo instanceof Bar
has to be an Expression3.But
foo instanceof Bar
is not an Expression3. There's no PrefixOp and no cast, so to be an Expression3 it would have to be a Primary. But it just doesn't fit.Conclusion: based solely on the grammar presented in Chapter 18,
foo instanceof Bar == false
is not a legal Java expression. !?!?!Of course that's nonsense.
foo instanceof Bar
yields a boolean result, and that result can certainly be compared tofalse
. The expression compiles and runs.Better conclusion: Chapter 18 isn't authoritative, but the rest of the book is.
Section 2.3 states that
By the grammar rules presented in Chapter 15,
foo instanceof Bar == false
is a legal Java expression. But check out the last sentence before section 15.20.1: "The type of a relational expression is always boolean." That directly conflicts with the RelationalExpression rules themselves in 15.20. (In particular, it implies that the LHS ofinstanceof
must evaluate to boolean.) It can't possibly be true.Bestest conclusion: This book has issues. If you want to know whether something is legal Java, you have to compile and run it, preferably on Oracle's reference implementation. And even then there might be bugs. It is, after all, just software.
And I think that if they changed the Expression2 rule just a little bit, Chapter 18 could be right. Like so:
But who knows, that might cause other problems. In any case, it's fixed in Java 8.