Это ошибка. Вот указанное поведение для оператора switch
в соответствии с Спецификацией языка Java, 3-е издание :
SwitchStatement:
switch ( Expression ) SwitchBlock
Когда выполняется оператор switch
, сначала оценивается Expression
. Если Expression
оценивается как null
, выдается NullPointerException
и по этой причине весь оператор switch
завершается внезапно.
Очевидно, что ошибка в Eclipse не имеет ничего общего с default
case или enum
вообще.
public class SwitchingOnAnull {
public static void main(String[] args) {
java.math.RoundingMode x = null;
switch(x) {};
switch((Integer) null) {};
switch((Character) null) {
default: System.out.println("I've got sunshine!");
}
}
}
Приведенный выше код компилируется и запускается "нормально" на (по крайней мере, в некоторых версиях) Eclipse. Каждый отдельный switch
выдает NullPointerException
при компиляции с javac
, что в точности соответствует требованиям спецификации.
Причина
Вот javap -c SwitchingOnAnull
при компиляции в Eclipse:
Compiled from "SwitchingOnAnull.java"
public class SwitchingOnAnull extends java.lang.Object{
public SwitchingOnAnull();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
5: ldc #22; //String I've got sunshine!
7: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
Кажется, что компилятор Eclipse полностью избавляется от конструкций switch
. К сожалению, эта оптимизация нарушает спецификацию языка.
Официальные слова
Ошибка была зарегистрирована и исправлена.
Olivier Thomann 2010-05-28 08:37:21 EDT
Мы слишком агрессивны в оптимизации.
Для:
switch((Integer) null) {};
мы оптимизируем весь оператор switch
, когда мы должны хотя бы оценить
выражение.
Я посмотрю.
Кандидат на 3.6.1.
Смотри также