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

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

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

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

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

5 ответов

Решение

Проблема в том, что все case: заявления должны быть окончательными во время компиляции. Ваше первое утверждение является окончательным. a не будет на 100% никакой другой ценности, кроме 5,

final int a = 5;

Однако это не гарантируется для b, Что делать, если вокруг будет if-заявление? b?

final int b;
if(something())
   b=6;
else
   b=5;

Что это значит?

Это означает, что "b" не является константным выражением времени компиляции, и JLS требует, чтобы оно было.

Когда и как конечным переменным присваивается значение?

Формально, когда выполняется оператор присваивания или инициализатор.

Но на практике, если final объявляет постоянную времени компиляции, выражение вычисляется во время компиляции, и его значение встроено в код.

Что происходит во время выполнения и что происходит во время компиляции?

Смотри выше.

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

Потому что JLS требует этого.

Компилятору байт-кода необходимо проверить, что оператор switch правильно сформирован; то есть, что значения констант переключения не сталкиваются. Это также позволяет компилятору JIT генерировать код, оптимизированный для фактических значений констант коммутатора.

Какие другие структуры Java требуют постоянной времени компиляции?

Ничего такого, о чём я могу думать, вне головы.

С точки зрения компилятора вы пытаетесь использовать переменную b, которая не может быть инициализирована. Оператор switch скомпилирован в табличный переключатель или байт-код JVM, который требует, чтобы значения, используемые в операторе 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

final int b; может быть назначен один раз, и значение не уверен, что будет решено во время выполнения в зависимости от условий. По этой причине, даже если она является конечной переменной, она не является константой ВРЕМЕНИ ВРЕМЕНИ, хотя она будет константой ВРЕМЕНИ РАБОТЫ, и для случая требуются константы времени компиляции.

Оператору switch нужна константа. Поскольку конечные переменные могут быть отложены, они инициализируются, и компилятор не может определить для b, что он имеет значение в ветви case.

Другие вопросы по тегам