Want some official clarification on a quirk about pattern-matching for instanceof

Cay Horstmann cay.horstmann at gmail.com
Wed Nov 15 21:55:34 UTC 2023


Here is my unofficial clarification.

Herbert Schildt is wrong when he says that "the right side of the & will not necessarily be evaluated". It will be. The difference between && and & with boolean operands is that & will evaluate both operands, but && will not evaluate the right operand if the left one is false.

You are right that in this context, it is plausible to think that iObj could have been declared.

Nevertheless, why use the & operator? Herbert Schildt could/should tell his readers that there is no reason to use & other than with bit patterns. Admittedly it is legal to use & with boolean operands in the very uncommon situation of a side effect in the second operand. But that's subtle and may well be surprising to readers of your code.

The Java Language Specification lays out rules to trace the scope of instanceof pattern definitions with && || ! and ?: operators. See https://docs.oracle.com/javase/specs/jls/se21/html/jls-6.html#jls-6.3.

There are no rules for & and | operators. I think that's because they were never intended for boolean logic but only for bit patterns (and perhaps unfortunately, side effects in boolean conditions). And I wholeheartedly agree with the decision not to add that complexity to the language rules.

My advice is to stay away from & and | for boolean operands. They were meant to fiddle with bits. For sure, don't use instanceof with those operators. With && and ||, and ! and ?:, the JLS rules are sensible and unsurprising.

Cheers,

Cay

PS. Many years ago, a C FAQ had this statement (https://www.lysator.liu.se/c/c-faq/c-5.html): The cost [of the C standard document] is $130.00 from ANSI . . .the Annotated ANSI C Standard, with annotations by Herbert Schildt . . . sells in the U.S. for approximately $40. It has been suggested that the price differential between this work and the official standard reflects the value of the annotations.





On 15/11/2023 03.34, David Alayachew wrote:
> Bumping this one up since I didn't receive a response.
> 
> On Fri, Nov 10, 2023 at 11:40 AM David Alayachew <davidalayachew at gmail.com <mailto:davidalayachew at gmail.com>> wrote:
> 
>     Hello Amber Dev Team,
> 
>     Someone on StackOverflow raised an excellent question about Pattern-Matching for instanceof, and I would like to get a response from one of you to include in the answer. Here is the link.
> 
>     https://stackoverflow.com/questions/77453336/instanceof-pattern-matching-in-java-not-compiling#77453336 <https://stackoverflow.com/questions/77453336/instanceof-pattern-matching-in-java-not-compiling#77453336>
> 
>     To summarize, the book that they were reading (Java: The Complete Reference, 12th Edition by Herbert Schildt) had the following quote.
> 
>     -----QUOTE_START---- (with minor modifications for readability)
> 
>     ```java
>     Number myOb = Integer.valueOf(9);
>     int count = 10;
> 
>     //                 vv---- Conditional AND Operator
>     if ( (count < 100) && myOb instanceof Integer iObj)
>     {
> 
>          iObj = count;
> 
>     }
>     ```
> 
>     The above fragment compiles because the if block will execute only when both sides of the && are true. Thus, the use of iObj in the if block is valid. However, a compilation error will result if you tried to use the & rather than the &&, as shown below.
> 
>     ```java
>     Number myOb = Integer.valueOf(9);
>     int count = 10;
> 
>     //                 v----- Bitwise Logical AND Operator
>     if ( (count < 100) & myOb instanceof Integer iObj)
>     {
> 
>          iObj = count;
> 
>     }
>     ```
> 
>     In this case, the compiler cannot know whether or not iObj will be in scope in the if block because the right side of the & will not necessarily be evaluated.
> 
>     ----QUOTE_END----
> 
>     When compiling the second example, it is exactly as the author says, we get told that the variable may not necessarily be in scope. Here is the error I get using OpenJDK 22 Early Access.
> 
>     ```java
>     $ java --version
>     openjdk 22-ea 2024-03-19
>     OpenJDK Runtime Environment (build 22-ea+20-1570)
>     OpenJDK 64-Bit Server VM (build 22-ea+20-1570, mixed mode, sharing)
> 
>     $ javac --version
>     javac 22-ea
> 
>     $ cat abc.java
>     public class abc
>     {
> 
> 
>          public static void main(String[] args)
>          {
> 
>              Number myOb = Integer.valueOf(9);
> 
>              int count = 10;
> 
>              if ( (count < 100) & myOb instanceof Integer iObj )
>              {
> 
>                  iObj = count;
> 
>              }
> 
>          }
> 
>     }
> 
>     $ javac abc.java
>     abc.java:15: error: cannot find symbol
>                      iObj = count;
>                      ^
>        symbol:   variable iObj
>        location: class abc
>     1 error
> 
>     ```
> 
>     I feel like I have a very good idea of why this might be the case, but I lack the terminology to put it into words correctly. Could someone help me out?
> 
>     Thank you for your time and help!
>     David Alayachew
> 

--

Cay S. Horstmann | http://horstmann.com | mailto:cay at horstmann.com


More information about the amber-dev mailing list