Я был немного уловлен этим поведением, и этот вопрос обнаружился при поиске в Google. Я думал, что поделюсь немного дополнительной информацией, которую я узнал.
javac 1.5 и 1.6 создают дополнительный синтетический класс каждый раз, когда вы используете переключатель enum. Класс содержит так называемую «карту переключения», которая отображает индексы перечисления для переключения номеров таблицы переходов. Важно отметить, что синтетический класс создается для класса, в котором происходит переключение, , а не класса enum.
Вот пример того, что генерируется:
EnumClass.java
public enum EnumClass { VALUE1, VALUE2, VALUE3 }
EnumUser.java
public class EnumUser {
public String getName(EnumClass value) {
switch (value) {
case VALUE1: return "value 1";
// No VALUE2 case.
case VALUE3: return "value 3";
default: return "other";
}
}
}
Synthetic EnumUser $ 1.class
class EnumUser$1 {
static final int[] $SwitchMap$EnumClass = new int[EnumClass.values().length];
static {
$SwitchMap$EnumClass[EnumClass.VALUE1.ordinal()] = 1;
$SwitchMap$EnumClass[EnumClass.VALUE3.ordinal()] = 2;
};
}
Эта карта переключателей затем используется для генерации индекса для инструкции JVM lookupswitch
или tableswitch
. Он преобразует каждое значение перечисления в соответствующий индекс от 1 до [количество случаев переключения].
EnumUser.class
public java.lang.String getName(EnumClass);
Code:
0: getstatic #2; //Field EnumUser$1.$SwitchMap$EnumClass:[I
3: aload_1
4: invokevirtual #3; //Method EnumClass.ordinal:()I
7: iaload
8: lookupswitch{ //2
1: 36;
2: 39;
default: 42 }
36: ldc #4; //String value 1
38: areturn
39: ldc #5; //String value 3
41: areturn
42: ldc #6; //String other
44: areturn
tableswitch
используется, если имеется три или более случая переключения, поскольку он выполняет более эффективный поиск в постоянном времени по сравнению с линейным поиском lookupswitch
. Технически говоря, javac может опустить весь этот бизнес с помощью синтетической карты переключателей, когда он использует lookupswitch
.
Предположение: У меня нет под рукой компилятора Eclipse для тестирования, но я думаю, что он не беспокоится о синтетическом классе и просто использует lookupswitch
. Или, возможно, для этого требуется больше переключателей, чем было проверено с оригинальным аскером, прежде чем он «вырастет» до tableswitch
.