Почему локальные переменные, включая примитивы, всегда должны инициализироваться в Java?

Почему локальные переменные, включая примитивы, всегда должны инициализироваться в Java? Почему то же самое не применимо в случае переменных экземпляра?

13.10.2009 14:44:41
Объявление неинициализированной локальной переменной возможно, но ее использование невозможно :)
kokabi 13.04.2017 12:04:18
8 ОТВЕТОВ
РЕШЕНИЕ

По сути, требовать, чтобы переменной было присвоено значение до того, как вы ее прочитаете. Это хорошая вещь. Это означает, что вы случайно не прочитаете то, что не собирались делать. Да, переменные могут иметь значения по умолчанию - но не лучше ли для компилятора уловить вашу ошибку, если он может доказать, что вы пытаетесь прочитать что-то, что еще не было назначено? Если вы хотите присвоить локальной переменной значение по умолчанию, вы всегда можете назначить это явно.

Теперь это хорошо для локальных переменных - но, например, для статических переменных, компилятор не может знать, в каком порядке будут вызываться методы. Будет ли свойство "setter" вызываться перед "getter"? У него нет возможности узнать, поэтому он не может предупредить вас об опасности. Именно поэтому значения по умолчанию будут использоваться, например , / статических переменных - по крайней мере , тогда вы получите известное значение (0, ложь, нуль и т.д.) , а не просто «что бы ни случилось быть в памяти в то время.» (Это также устраняет потенциальную проблему безопасности чтения конфиденциальных данных, которые не были явно стерты.)

Был вопрос об этом совсем недавно для C # ... - также прочитайте ответы там, поскольку это в основном то же самое. Вы также можете найти недавнее сообщение в блоге Эрика Липперта интересным; это, по крайней мере, вокруг той же области, хотя у него несколько иная тяга.

74
9.08.2019 05:03:11
Что я не понимаю, так это то, что если объект по умолчанию равен нулю, почему вы должны присвоить ему значение null? Я предполагаю, что люди на языке Java решили, что в этом случае лучше быть явным, но я не уверен, согласен ли я.
James McMahon 13.10.2009 16:00:39
Объект не является нулевым. Переменная может быть пустым, но не является объектом. А локальная переменная не имеет значения по умолчанию ... именно потому, что ее отсутствие означает, что вы вынуждены дать ей полезное значение перед ее чтением. Если вы хотите сделать это значение нулевым, это нормально ... но мне больше нравится, когда компилятор говорит мне, пытаюсь ли я прочитать что-то, что могло не инициализироваться ...
Jon Skeet 13.10.2009 16:03:40
@Jon Что вы подразумеваете под «Это также устраняет потенциальную проблему безопасности чтения конфиденциальных данных, которые не были явно стерты». ? Можете ли вы объяснить это немного?
Geek 31.07.2012 11:15:54
Отличный ответ, инициализация в ноль и знание того, что ожидать, намного лучше, чем случайный вывод. Это хорошее ограничение, чтобы иметь.
kiwicomb123 28.03.2017 11:57:28

Локальные переменные и примитивы должны быть инициализированы перед использованием, потому что вы будете знать, чего ожидать от значений. Исторически, когда создавалась новая переменная, она содержала случайные значения из памяти [и никто не мог предсказать значение]. Java также требует этого, потому что это предотвращает присутствие потерянных переменных.

1
13.10.2009 14:48:34

На практике все переменные должны быть инициализированы перед их использованием.

Я не могу вспомнить время, когда вы захотите использовать переменную перед установкой ее значения (если вы не сравниваете ее с нулем).

1
13.10.2009 14:49:15

Что ж, в случае с локальной переменной ясно, что это означает «до», поскольку поток программы между объявлением (в методе) и ссылкой является последовательным. В случае полей, объявленных вне метода, компилятор никогда не знает, какой код будет использоваться, когда он не может генерировать ошибку, так как, возможно, какой-то другой метод будет инициализировать поле перед его использованием.

8
13.10.2009 14:49:52
+1 за «поток программы между объявлением (в методе) и ссылкой является последовательным».
luigi7up 30.01.2013 18:07:25

Не совсем верно Локальные переменные нужно только инициализировать, если они являются ссылочными. Локальная переменная может оставаться неинициализированной, если на нее никогда не ссылаются. Например:

int x;  // Valid
int y;
println("y=" + y);  // Not valid since y's value has never been assigned
7
13.10.2009 15:53:03

В Java переменные класса и экземпляра принимают значение по умолчанию (null, 0, false), если они не инициализированы вручную. Однако локальные переменные не имеют значения по умолчанию. Если локальной переменной не присвоено значение, компилятор откажется компилировать код, который ее читает. ИМХО, это приводит к выводу, что инициализация локальной переменной с некоторым значением по умолчанию (например, null, которое может привести к исключению NullPointerException позже), когда она объявлена, на самом деле плохая вещь. Рассмотрим следующий пример:

Object o;
if (<some boolean condition>)
  o = <some value>;
else
  o = <some other value>;
System.out.println(o);

Инициализация oс помощью null совершенно не нужна, так как компилятор Java проверяет во время компиляции, что любой путь кода инициализируется o(с нулевым или некоторым ненулевым значением) перед чтением переменной. Это означает, что компилятор откажется компилировать строку, System.out.println(o);если вы закомментируете любую из двух инициализаций переменной oв приведенном выше фрагменте кода.

Это относится и к Java, и, возможно, только к Java. Я не знаю о языке, как C #. В старом добром C (и, возможно, C ++) все же рекомендуется всегда инициализировать переменные при объявлении их, AFAIK. Такие "старые школы" языки программирования могут быть причиной того, что рекомендация всегда инициализировать переменные появляется в книгах и дискуссиях о современных языках, таких как Java, где компилятор отслеживает, была ли переменная инициализирована или нет.

8
28.03.2019 21:03:29
Языки «старой школы» рекомендуют не объявлять переменную до тех пор, пока вы не введете значение. :-)
Bo Persson 14.01.2012 15:30:11
Рассмотрим пример выше. Как вы можете иметь значение для помещения в переменную, если значение зависит от результата сложного оператора if. ИМХО, правило, которое вы предлагаете, имеет большую проблему.
Sven 13.05.2016 14:22:29
Если значение требует некоторых сложных вычислений, вы можете поместить их в отдельную функцию и использовать вызов функции в качестве инициализатора.
Bo Persson 13.05.2016 14:27:39

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

И как основное правило, мы всегда должны инициализировать любую переменную перед ее использованием. В противном случае это может привести к ошибке типа nullPointer и т. Д.

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

Поэтому, когда стек завершится, значение локального метода также будет уничтожено, поэтому: 1] Они должны быть инициализированы явно (когда мы их используем) 2] Они не должны быть инициализированы неявно (нулевыми, 0 или ложными) как переменные экземпляра

1
3.06.2018 11:19:27

Исходя из определения локальной переменной, состояние которой, локальная переменная объявляется внутри функции или передается в качестве аргумента функции. Если вы не инициализировали локальную переменную, вы столкнетесь с проблемой обработки исключений, потому что компилятор не сможет понять, какое значение содержит переменная

0
8.12.2018 13:38:18