Почему конечная переменная всегда является постоянным выражением?
В приведенном ниже коде:
final int a;
a=2;
byte b=a; // error: possible loss of precision
Почему я получаю эту ошибку? Является ли a
окончательная переменная времени компиляции постоянной константы и, следовательно, неявно сужается до байта во время назначения?
Другими словами, не приведенный выше код эквивалентен:
final int a=2;
byte b=a;
Ответы
Ответ 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.