Почему нет ошибки компиляции в строке выше указанной строки? - PullRequest
3 голосов
/ 10 апреля 2011

Я читаю на Java и чесаю голову, почему System.out.println("a: " + a); не приводит к ошибке компиляции.Где a когда-либо инициализируется?

public class localVariableEx {
    public static int a;
    public static void main(String[] args) {
        int b;
        System.out.println("a: " + a);
        System.out.println("b: " + b);  //Compilation error
    }
}

Ответы [ 3 ]

9 голосов
/ 10 апреля 2011

Соответствующие правила этого описаны в JLS § 4.12.5 Начальные значения переменных (выделено мной):

  • Каждая переменная класса , переменная экземпляра или компонент массива инициализируется значением по умолчанию при создании ( §15.9, §15.10 ): [...]
  • [...]
  • A локальная переменная ( §14.4 , §14.14 ) должно быть явно задано значение перед использованием, либо инициализация ( §14.4 ) или присваивание ( §15.26 ) способом, который может быть проверен компилятором с использованием правил для определенного присваивания ( §16 ) .

Таким образом, в то время как переменные экземпляра (такие как a) автоматически получают значение по умолчанию, локальные переменные (такие как b) не получают его и не должны использоваться, если компилятор не может проверить, что значение было присвоено им.

8 голосов
/ 10 апреля 2011

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

0 голосов
/ 10 апреля 2011

a имеет примитивный тип int, который будет немедленно инициализирован, что означает:

Статические члены класса: получить init'ed при загрузке класса (большинствовремени, когда раньше main(), но это зависит от того, когда класс загружается).

class S {
  static int a;
}

Нестатические члены класса: получить init'ed, когда объектявляется.(в большинстве случаев после new, но существуют другие, более продвинутые методы для создания нового объекта).

class S {
  int a;
}

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

class S {
  void foo() {
    int b = 0;
  }
}

редактируется после исправления ...

...