Эта ситуация описана в JLS 8.3.2.3"Ограничения на использование полей при инициализации".
Правила JLS разрешают использование в вашем Вопросе и утверждают, что первый вызов getc()
вернет значение по умолчанию (неинициализированное) alex
.
Однако правила запрещают использование неинициализированных переменных; например,
int i = j + 1;
int j = i + 1;
не разрешено.
Re некоторые другие ответы. Это не тот случай, когда компилятор Java "не может понять это". Компилятор строго реализует то, что указано в Спецификации языка Java. (Или, иначе говоря, можно написать компилятор , чтобы обнаружить округлость в вашем примере и назвать это ошибкой компиляции. Однако, если бы он это сделал, он отклонил бы действительные программы Java, и поэтому не будет совместимым компилятором Java.)
В комментарии вы заявляете это:
... конечные поля всегда должны быть инициализированы во время компиляции или во время выполнения до создания объекта.
Это не правильно.
На самом деле существует два вида полей final
:
Так называемая «постоянная переменная» действительно оценивается во время компиляции. (Постоянная переменная - это переменная "примитивного типа или типа String, которая является конечной и инициализируется константным выражением времени компиляции" - см. JLS 4.12.4.). Такое поле всегда будет инициализировано к тому времени, когда вы получите к нему доступ ... по модулю некоторых осложнений, которые здесь не имеют отношения.
Другие поля final
инициализируются в порядке, указанном JLS, и позволяет увидеть значение поля до его инициализации. Ограничение final
переменных заключается в том, что они должны инициализироваться один раз и только один раз во время инициализации класса (для static
) или во время инициализации объекта.
Наконец, этот материал очень похож на поведение в «угловом корпусе». Типичный хорошо написанный класс не нужно
получить доступ к полю final
до его инициализации.