Является ли «ошибка: переменная а, возможно, не инициализирована» действительно необходимо в этой конструкции if? - PullRequest
0 голосов
/ 29 сентября 2018

Как мне сказать Java, что мне не нужно инициализировать a, чтобы иметь работающую программу и не выдавать мне ошибку?

int a;
boolean b = true;
while (true) {
   if (b == false) {
       System.out.print(a);
       break;
   } else {
       b = false;
       a = 5;
   }
}

И если я не могу, есть липричина, почему так устроен компилятор?

Было ли легко спроектировать такой компилятор или это механизм, обеспечивающий реструктуризацию моего кода?

Это не тот же вопрос, что и этот

1 Ответ

0 голосов
/ 29 сентября 2018

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...