Разница между конечными переменными и постоянной времени компиляции
В чем разница между конечными переменными и константами времени компиляции?
Рассмотрим следующий код
final int a = 5;
final int b;
b=6;
int x=0;
switch(x)
{
case a: //no error
case b: //compiler error
}
Что это значит? Когда и как конечные переменные присваивают значение? Что происходит во время выполнения и что происходит во время компиляции? Почему мы должны предоставлять переменную времени компиляции? Какие еще структуры Java требуют постоянной времени компиляции?
Ответы
Ответ 1
Проблема заключается в том, что все case:
утверждения должны быть окончательными во время компиляции.
Ваше первое утверждение предельно. a
для 100% не будет другого значения, чем 5
.
final int a = 5;
Однако это не гарантируется для b
. Что, если бы был if-statement вокруг b
?
final int b;
if(something())
b=6;
else
b=5;
Ответ 2
Что это значит?
Это означает, что "b" не является выражением постоянной времени компиляции, и JLS требует, чтобы это было.
Когда и как конечные переменные присваивают значение?
Формально, когда выполняется оператор присваивания или инициализатор.
Но на практике, если final
объявляет постоянную времени компиляции, выражение оценивается во время компиляции, и его значение жестко связано с кодом.
Что происходит во время выполнения и что происходит во время компиляции?
См. выше.
Почему мы должны указывать переменную времени компиляции?
Потому что JLS требует его.
Для компилятора байт-кода необходимо убедиться, что оператор switch хорошо сформирован; то есть значения констант переключателя не сталкиваются. Он также позволяет компилятору JIT генерировать код, оптимизированный для фактических значений констант коммутатора.
Какие другие структуры java требуют постоянной времени компиляции?
Нет, о чем я могу думать, с головы.
Ответ 3
С точки зрения компилятора вы пытаетесь использовать переменную b, которая не может быть инициализирована . Оператор switch скомпилирован в JVM byteecode tableswitch или lookupswitch, который требует, чтобы значения, используемые в выражении case , были как константой времени компиляции, так и уникальны.
final int a = 4; // compiler is sure a is initialized
final int b;// variable b is not guranted to be assigned
например.
Хотя этот оператор в конечном счете инициализирует b, но компилятор не может его обнаружить.
if (a < 4) b= 10;
if (a >= 4) b = 8
Ответ 4
Оператор switch нуждается в константе. Поскольку конечные переменные могут быть отложены инициализированы и компилятор не может определить для b, что он имеет значение в ветки case.
Ответ 5
final int b;
может быть назначен один раз, а значение не определено, что будет определено в время выполнения в зависимости от условий. это причина, даже если она является переменной final, она не является константой COMMILE TIME, хотя это будет константа RUN TIME и в случае необходимости константы времени компиляции.