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

Java: Почему мне требуется инициализировать примитивную локальную переменную?

public class Foo {
    public static void main(String[] args) {
        float f;
        System.out.println(f);
    }
}

Оператор печати вызывает следующую ошибку времени компиляции,

Локальная переменная f может не быть инициализирована

Если примитивы в Java уже имеют значение по умолчанию (float = 0.0f), почему я должен определить один?


Изменить:

Итак, это работает

public class Foo {
    float f;
    public static void main(String[] args) {
        System.out.println(new Foo().f);
    }
}

Спасибо, всем!

4b9b3361

Ответ 1

Потому что это локальная переменная. Вот почему ничего ему не назначено:

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

Изменить: почему Java вызывает ошибку компиляции? Если мы посмотрим на файл класса IdentifierExpression.java, мы найдем этот блок:

...
if (field.isLocal()) {
            LocalMember local = (LocalMember)field;
            if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) {
                env.error(where, "invalid.uplevel", id);
            }
            if (!vset.testVar(local.number)) {
                env.error(where, "var.not.initialized", id);
                vset.addVar(local.number);
            }
            local.readcount++;
        }
...

Как указано (if (!vset.testVar(local.number)) {), JDK проверяет (с помощью testVar), если назначается переменная (Vset исходный код где мы можем найти код testVar). Если нет, он вызывает ошибку var.not.initialized из файла свойств :

...
javac.err.var.not.initialized=\
    Variable {0} may not have been initialized.
...

Источник

Ответ 2

Фактически, компилятор не присваивает значение по умолчанию вашему float f, потому что в этом случае это локальная переменная, а не поле:

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

Ответ 3

Поля классов (не равно final в любом случае) инициализируются значениями по умолчанию. Локальные переменные не являются.

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

Итак, поле (не final), подобное f в

class C {
  float f;
}

будет инициализироваться на 0f, но локальная переменная f в

void myMethod() {
  float f;
}

не будет.

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

Ответ 4

Фактически локальные переменные хранятся в стеке. Существует вероятность получить любое старое значение для локальной переменной. Это большая проблема для соображений безопасности. Java говорит, что перед использованием вы должны инициализировать локальную переменную.

Ответ 5

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