Почему `switch (null)` является ошибкой компиляции, но `switch (str)` подходит для str, являющегося `static final String str = null;`? - PullRequest
3 голосов
/ 04 июня 2019

Хотя switch(null) - это ошибка компиляции, но switch(str) в порядке (str означает static final String str = null;).

Не является ли static final String str = null; константой времени компиляции, которая должна быть подставлена ​​в switch(str) во время компиляции и, таким образом, эквивалентна switch(null)?

switch (null) {  // compile Error immediately!

}

НО:

public class Test {

    // compile-time constant?
    static final String s4 = null; 

    public static void main(String[] args) {

        switch (s4) {  // compiles fine! NPE at runtime

        }
    }
}

PS Полагаю, static final String str = null; НЕ является константой времени компиляции, потому что только static final String str = 'string literal' является константой времени компиляции , что объясняет пример выше (s4).

Ответы [ 2 ]

7 голосов
/ 04 июня 2019

Из сообщения об ошибке:

Несовместимые типы. Найдено 'null', обязательно: 'char, byte, short, int, Character, Byte, Integer, String или enum'

Вы можете видеть, что null подразумевается ни к чему, это даже не Object, это - это просто "нулевой тип", а не String (или любой другой допустимый переключаемый параметр) тип).

Так что для его компиляции вам нужно привести его к String (или к одному из других допустимых типов).

switch((String) null) {

Который затем выдает RuntimeException при попытке выполнить его.

Это поведение применимо не только к switch, оно фактически такое же, как когда вы делаете это:

null.isEmpty()

Откуда Java должен знать, что вы хотите вызвать String#isEmpty()? Вы могли бы также иметь в виду Collection#isEmpty(). Или любой другой метод isEmpty(). То же самое относится к примеру switch, java просто не знает, какой тип вы имеете в виду.

3 голосов
/ 04 июня 2019

С Документ Oracle :

В отличие от операторов if-then и if-then-else, оператор switch может иметь несколько возможных путей выполнения. Переключатель работает с байтовые, короткие, char и int примитивные типы данных. Это также работает с перечислимые типы (обсуждаемые в Enum Types), класс String и несколько специальных классов, которые обертывают определенные примитивные типы: Byte, Short и Integer (обсуждается в Numbers и Strings).

Следовательно, switch(null) недопустимо, поскольку вы не можете включить любое значение (null может быть нулевым Banana объектом, который не поддерживается)

...