Подтвердить что ты не робот

Разница между конечными переменными и постоянной времени компиляции

В чем разница между конечными переменными и константами времени компиляции?

Рассмотрим следующий код

final int a = 5;
final int b;
b=6;
int x=0;
switch(x)
{
     case a: //no error
     case b: //compiler error
}

Что это значит? Когда и как конечные переменные присваивают значение? Что происходит во время выполнения и что происходит во время компиляции? Почему мы должны предоставлять переменную времени компиляции? Какие еще структуры Java требуют постоянной времени компиляции?

4b9b3361

Ответ 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 и в случае необходимости константы времени компиляции.