Ответ 1
Каковы фоны для случая коммутатора, чтобы не принимать этот оператор?
Потому что case
требует постоянного выражения в качестве значения. А поскольку выражение ||
не является константой времени компиляции, это недопустимо.
От JLS Раздел 14.11:
Знак коммутатора должен иметь следующий синтаксис:
SwitchLabel:
case ConstantExpression:
case EnumConstantName:
default:
Под капотом:
Причина, позволяющая просто постоянное выражение в случаях, может быть понята из JVM Spec Section 3.10 - Компиляция переключателей:
Компиляция операторов switch использует инструкции tableswitch и lookupswitch. Команда tableswitch используется, когда случаи коммутатора могут быть эффективно представлены в виде индексов в таблицу целевых смещений. Цель по умолчанию для коммутатора используется, если значение выражения коммутатора выходит за пределы допустимых индексов.
Итак, для ярлыка case, который будет использоваться tableswitch
в качестве индекса в таблице смещений цели, значение случая должно быть известно во время компиляции. Это возможно только в том случае, если значение case является постоянным выражением. И выражение ||
будет оцениваться во время выполнения, и значение будет доступно только в это время.
В том же разделе JVM: switch-case
:
switch (i) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
default: return -1;
}
скомпилирован для:
0 iload_1 // Push local variable 1 (argument i)
1 tableswitch 0 to 2: // Valid indices are 0 through 2 (NOTICE This instruction?)
0: 28 // If i is 0, continue at 28
1: 30 // If i is 1, continue at 30
2: 32 // If i is 2, continue at 32
default:34 // Otherwise, continue at 34
28 iconst_0 // i was 0; push int constant 0...
29 ireturn // ...and return it
30 iconst_1 // i was 1; push int constant 1...
31 ireturn // ...and return it
32 iconst_2 // i was 2; push int constant 2...
33 ireturn // ...and return it
34 iconst_m1 // otherwise push int constant -1...
35 ireturn // ...and return it
Итак, если значение case
не является константным выражением, компилятор не сможет проиндексировать его в таблицу указателей команд, используя инструкцию tableswitch
.