instanceof with primitive type

Ella Ananeva ella.ananeva at oracle.com
Thu Nov 9 18:52:38 UTC 2023


Thank you so much for clarification, Brian.


From: Brian Goetz <brian.goetz at oracle.com>
Date: Wednesday, November 8, 2023 at 5:38 PM
To: Ella Ananeva <ella.ananeva at oracle.com>, Angelos Bimpoudis <angelos.bimpoudis at oracle.com>, amber-dev at openjdk.org <amber-dev at openjdk.org>
Subject: Re: instanceof with primitive type
Unfortunately the behavior of instanceof and switch has always been different on this matter; instanceof evaluates to false when presented with a null, and switch throws NPE when presented with a null.  (They both dislike nulls, but one is more tolerant than the other.)

When we added pattern support to switch, we extended this behavior to support `null` case labels.  If a switch has a `case null`, then when given a null selector, the appropriate case will be run, rather than the switch completing abruptly with NPE.  This preserves compatibility with existing code, while enabling null to be treated as "just another value" if desired.

So the NPE you are seeing is not coming from the unboxing operation in `case byte x`, but before we even enter the switch, because the first thing switch does is evaluate the selector, and if that succeeds, checks for null, and if null, and no `case null` present, the switch completes abruptly with NPE.

On 11/8/2023 6:08 PM, Ella Ananeva wrote:
Thank you very much for addressing this issue, Angelos!

I have another question. What is our approach to treating scenarios when we use instanceof of null type with cast?

Byte b = null;
If (!(b instanceof byte))  System.our.println(“Yes”); //prints “Yes”

In the spec,

A reference conversion may not complete normally, namely:

  1.  An unboxing conversion may raise a NullPointerException

Here, no exception is thrown., so the behavior is as if we had a null type instanceof with a reference type in the pattern. But we have a primitive type in the pattern, so I would assume there should be some conversion going on? Precisely the scenario described in the assertion? BTW if I do a similar thing in switch, there will be an exception:

Byte y = null;
try {
    switch (y) {
        case byte x: System.out.println("converted");
        default: System.out.println("not converted");
    }
} catch (NullPointerException ex) {
    System.out.println("Threw exception");
}

This code prints “Threw exception.”

Shouldn’t the behavior of switch and instanceof be similar in this situation?

Thank you,
Ella

From: Angelos Bimpoudis <angelos.bimpoudis at oracle.com><mailto:angelos.bimpoudis at oracle.com>
Date: Wednesday, November 8, 2023 at 2:56 PM
To: Ella Ananeva <ella.ananeva at oracle.com><mailto:ella.ananeva at oracle.com>, amber-dev at openjdk.org<mailto:amber-dev at openjdk.org> <amber-dev at openjdk.org><mailto:amber-dev at openjdk.org>
Subject: Re: instanceof with primitive type
Hello Ella,

Indeed. The bullet you showed is now deleted from both. The line you have put in bold, replaces the other two.

Thanks for bringing this up.
Aggelos
________________________________
From: amber-dev <amber-dev-retn at openjdk.org><mailto:amber-dev-retn at openjdk.org> on behalf of Ella Ananeva <ella.ananeva at oracle.com><mailto:ella.ananeva at oracle.com>
Sent: 08 November 2023 19:18
To: amber-dev at openjdk.org<mailto:amber-dev at openjdk.org> <amber-dev at openjdk.org><mailto:amber-dev at openjdk.org>
Subject: instanceof with primitive type


Hi team,

Reading JEP 455 spec<https://cr.openjdk.org/~abimpoudis/instanceof/jep455-20231030/specs/instanceof-jls.html#jls-15.20.2>, I see this:

The type of the expression RelationalExpression can be a reference type, a primitive type or the null type.

And then, later:

The following rules apply when instanceof is the pattern match operator:

  1.  The type of the expression RelationalExpression must be a reference type or the null type, or a compile-time error occurs.



But I would expect that primitive types in patterns should be good, too. And in the freshest version of JEP_455 JDK<https://mach5.us.oracle.com/mdash/buildIds/2023-11-06-1633093.angelos.bimpoudis.dev>, both examples compile and print “Yes”:



Integer x = 5;
if (x instanceof int y) System.out.println("Yes");



int x = 5;
if (x instanceof Integer y) System.out.println("Yes");



Shouldn’t the spec be updated?



Thank you,

Ella Ananeva

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20231109/d0336357/attachment-0001.htm>


More information about the amber-dev mailing list