Почему унитизированный объект в Java не имеет нулевого значения? - PullRequest
4 голосов
/ 22 декабря 2011

У меня здесь очень простая проблема, которую я не смог найти, хотя она должна существовать.

У меня есть следующий код:

public class Foo {
    public static void main(String[] args) {
        String foo;
        if (foo != null) {
            System.out.println("foo");
        } else {
            System.out.println("foo2");
        }
    }
}

Это дает мне

'' переменная, возможно, не была инициализирована ''

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

Ответы [ 5 ]

15 голосов
/ 22 декабря 2011

Предотвращает случайное использование локальной переменной до того, как она будет определенно назначена.Это хорошая вещь - она ​​помогает предотвратить ошибки.Обидно, что это нельзя сделать для полей (экземпляра и статических переменных) - но, кроме конечных переменных, компилятор не знает, когда вы собираетесь их читать, а когда вы их назначаете - онне могу определить порядок, в котором вы собираетесь вызывать методы.Внутри одного метода он имеет гораздо больше информации об управлении потоком, поэтому может предоставить больше проверок для вас.

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

См. главу 16 спецификации языка Java для получения более подробной информации об определенном назначении.* Вот пример того, как это может предотвратить ошибки:

Iterable<String> collectionOfNames = ...; // Some method call
String lastNameInCollection;
for (String name : collectionOfNames)
{
    lastNameInCollection = name;
}
System.out.println("The last name was: " + lastNameInCollection);

Что должно произойти, если коллекция пуста? Может быть мы хотим напечатать «Фамилия была: ноль» - но, возможно, мы должны сделать что-то еще.Тот факт, что вышеперечисленное не скомпилируется (так как lastNameIncollection не может быть назначен), заставляет программиста задуматься о случае, когда коллекция имен пуста.

2 голосов
/ 22 декабря 2011

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

String variable;
if (conditionA) {
    if (conditionB)
        variable = "B";
    else
        variable = "A";
} else {
    switch (conditionC) {
    case 1:
        variable = "C1";
        break;
    case 2:
        variable = "C2";
        break;
    default:
        variable = "CD";
        break;
    }
}
System.out.println(variable.length());

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

String variable = null;
if (conditionA)
    variable = "A";
// NullPointerException if conditionA is false, not check by compiler
System.out.println(variable.length());

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

final int variable;
if (condition)
    variable = 1;
else
    variable = 2;
1 голос
/ 22 декабря 2011

Также может быть совершенно не нужно инициализировать его, если оно будет инициализировано определенно позже:

    String foo;
    if (specialUseCase) {
        foo = "this";
    } else {
        foo = "that";
    }
1 голос
/ 22 декабря 2011

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

Этот код будет работать

public class Foo {
  String foo;
  public static void main(String[] args) {
    if (foo != null) {
        System.out.println("foo");
    } else {
        System.out.println("foo2");
    }
  }
}

Или этот

public class Foo {
  public static void main(String[] args) {
    String foo = null;
    if (foo != null) {
        System.out.println("foo");
    } else {
        System.out.println("foo2");
    }
  }
}

Если вы хотите получить полное глубокое понимание этого вопроса, рассмотрите ответ Джона Скита и проверьте предоставленную им ссылку.

0 голосов
/ 22 декабря 2011

Поскольку локальные переменные не инициализируются автоматически, вы должны явно инициализировать их. Только переменные-члены инициализируются нулевым значением или значением по умолчанию, даже если вы не инициализируете явно. Если вы оставите String foo; вне метода main (), вам не нужно инициализировать.

...