[17][Pattern Switch] NPE not thrown for a null with default, (non-total) type pattern case labels

Alex Buckley alex.buckley at oracle.com
Fri Aug 20 17:20:57 UTC 2021

It would be ideal for 14.11.1 to say, in a note, what every reader will 
otherwise be pondering: "Note that a default switch label never applies 
to a null value."


On 8/20/2021 5:41 AM, Brian Goetz wrote:
> Agree, this should NPE.
> On 8/20/2021 7:37 AM, Manoj Palat wrote:
>> Hi,
>>  Consider the following case:
>> class X {
>> public void foo(Object o) {
>>          switch (o) {
>>            default: break;
>>            case String s :System.out.println(s); break;
>>          }
>> }
>> public static void main(String[] args) {
>>          (new X()).foo(null); // NPE expected, but prints null
>> }
>> }
>> javac (17+ea35)  prints a null rather than an NPE. I believe it should 
>> throw NullPointerException (rather  javac should generate code for 
>> Null check to raise NPE at run-time).
>> Reasoning behind this is [based on 
>> https://cr.openjdk.java.net/~gbierman/jep406/jep406-20210608/specs/patterns-switch-jls.html#jls-14.11.3 
>> <https://cr.openjdk.java.net/~gbierman/jep406/jep406-20210608/specs/patterns-switch-jls.html#jls-14.11.3>]:
>> section 14.11.3, see the second rule:
>> ...
>> Otherwise, if the result of evaluating the selector expression is null, and no switch label in the resolved switch block applies then a NullPointerException is thrown...
>> I don't think either of the switch labels apply here
>> [based on sec 14.11.1
>> If the value is the null reference, then we determine the first (if any) switch label in the switch block that applies to the value as follows:
>> A switch label...]
>> Hence I believe an NPE should be thrown for null.
>> [A longer version of reasoning at: 
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=575051#c4 
>> <https://bugs.eclipse.org/bugs/show_bug.cgi?id=575051#c4>]
>> Please let me know your take on this.
>> Regards,
>> Manoj
>> [Note: If the case labels are swapped, ie if its in the order shown 
>> below, NPE is thrown at run-time
>> case String s :System.out.println(s); break;
>> default: break; ]

More information about the compiler-dev mailing list