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

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

В приведенном ниже коде:

final int a;
a=2;
byte b=a;   // error: possible loss of precision

Почему я получаю эту ошибку? Является ли a окончательная переменная времени компиляции постоянной константы и, следовательно, неявно сужается до байта во время назначения?

Другими словами, не приведенный выше код эквивалентен:

final int a=2;
byte b=a;
4b9b3361

Ответ 1

Компилятор не настолько умный.

Мы можем сказать, что значение всегда будет равно 2. Но что, если бы у нас было что-то вроде этого?

class ABC{
    final int a;

    public ABC(){
       if(Math.random() < .5){
          a = 2;
       }
       else{
          a = 12345;
       }

       byte b = a;
    }
}

Компилятор недостаточно умен, чтобы рассказать обо всех этих случаях, поэтому он дает вам ошибку.

Ответ 2

Из JLS

Пусто final - это переменная final, в декларации которой отсутствует инициализатор.

Постоянная переменная является переменной final примитивного типа или типа String, который инициализируется константным выражением (§15.28).

Ваша переменная

final int a;

является пустой переменной final. Ему не хватает инициализатора. Второй абзац не применяется к нему, поскольку он не инициализируется при объявлении. Следовательно, это не постоянное выражение.

Это относится и к полям.

Ответ 3

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