Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

Теперь, когда это нормально для локальных переменных, но, например, для статических переменных, компилятор не может знать порядок, в котором будут вызваны методы. Будет ли вызвано свойство "сеттер" перед "геттером"? Он не может знать, поэтому он не может предупредить вас об опасности. Поэтому значения по умолчанию используются для экземпляров/статических переменных - по крайней мере, тогда вы получите известное значение (0, false, null и т.д.), А не просто "все, что было в памяти в то время". (Он также устраняет потенциальную проблему безопасности чтения конфиденциальных данных, которые не были явно стерты.)

Ответ 2

В 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 с нулевым значением совершенно не требуется, так как компилятор Java проверяет во время компиляции, что любой путь кода инициализирует o (с нулевым или некоторым ненулевым значением) перед чтением переменной. Это означает, что компилятор откажется откомпилировать строку System.out.println(o); если вы закомментируете любую из двух инициализаций переменной o в приведенном выше фрагменте кода.

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

Ответ 3

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

Ответ 4

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

int x;  // Valid
int y;
println("y=" + y);  // Not valid since y value has never been assigned

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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