Ответ 1
Это ошибка. Здесь указано поведение оператора switch
в соответствии с Спецификацией языка Java, 3-е издание:
JLS 14.11 Заявление switch
SwitchStatement: switch ( Expression ) SwitchBlock
Когда выполняется оператор
switch
, сначала оцениваетсяExpression
. ЕслиExpression
оценивается какnull
, aNullPointerException
выбрасывается, и по этой причине завершается весь операторswitch
.
По-видимому, ошибка в Eclipse не имеет никакого отношения к случаю default
или 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
. К сожалению, эта оптимизация нарушает спецификацию языка.
Официальные слова
Ошибка исправлена и назначена для исправления.
Оливье Томман 2010-05-28 08:37:21 EDT
Мы слишком агрессивны в оптимизации.
Для:
switch((Integer) null) {};
мы оптимизируем весь оператор
switch
, когда мы должны хотя бы оценить выражение.Я посмотрю.
Кандидат на 3.6.1.