Is 'ошибка: переменная a, возможно, не была инициализирована' действительно необходима в этом случае, если она создана?
Да, это необходимо.Спецификация языка Java требует этого.Это рассматривается в JLS 16 - Определенное назначение .
"Каждая локальная переменная (§14.4) и каждое пустое конечное поле (§4.12.4, §8.3.1.2) должен иметь однозначно присвоенное значение при любом доступе к его значению. "
Как мне сообщить Java, что мне не нужно инициализировать a
иметь работающую программу и не выдавать мне ошибку?
Вы не можете сказать Java об этом.Вам нужно инициализировать переменную ... или реструктурировать код.
И если я не могу, есть ли причина, по которой так был разработан компилятор?
Поскольку компилятор Java должен реализовать спецификацию, в противном случае он не является надлежащим компилятором Java.В спецификации говорится, что это ошибка.
Реальный вопрос в том, почему в спецификации это сказано.Ответ таков: авторы компиляторов не обязаны включать сложный доказательство теоремы код во все компиляторы Java.
В приведенном вами примере это очевидноПрограммист, что переменная всегда будет инициализирована.Однако компилятор должен это проверить.Необходимо быть абсолютно уверенным, поскольку неинициализированная переменная будет иметь поведение undefined .
Автоматическая (неориентированная) проверка является сложной задачей.Сложный означает больше (компилятор) кода для написания, больше (компилятор) ошибок, и так далее.
«Современное состояние» в этой технологии не до такого анализа длясложный код Java.
Существуют (теоретические) случаи, когда проверка инициализации переменной математически невозможна .
Итак ... мудро ... люди, которые указали язык Java, отодвинули это назад к программисту.Вы должны написать свой код так, чтобы переменные были определенно назначены перед использованием, в соответствии с правилами, изложенными в JLS.
И есть и вторая причина.Предположим, что JLS разрешил компилятору Java принимать
System.out.print(a);
тогда и только тогда, когда мог бы убедиться в том, что a
был (всегда) ранее инициализирован.Теперь рассмотрим два Java-компилятора, написанных разными людьми (или одними и теми же людьми в разное время) для реализации одной и той же версии JLS.
Компилятор C1 может выяснить, что a
всегдаинициализируется и говорит, что программа действительна.
Компилятор C2 не может выяснить, что a
всегда инициализируется, и говорит, что программа недействительна.
Теперь у нас есть два компилятора Java, которые якобы реализуют одну и ту же версию JLS, но не согласны с тем, допустима ли ваша примерная программа (см. Выше).Это просто несостоятельно.
Чтобы еще больше усложнить ситуацию, я подозреваю, что что-то похожее на проверку "определенного назначения" также должно происходить, когда JVM проверяет только что загруженные байт-коды.Таким образом, изменение правил определенного присваивания JLS может повлиять на JVMS и потенциально повлиять на поведение платформы JVM для других языков программирования и инструментов , которые компилируются / генерируются непосредственно в байт-коды JVM.