Почему компилятор Java жалуется на то, что локальная переменная здесь не инициализирована? - PullRequest
3 голосов
/ 02 марта 2010
int a = 1, b;
if(a > 0) b = 1;
if(a <= 0) b = 2;
System.out.println(b);

Если я запускаю это, я получаю:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
 The local variable b may not have been initialized

 at Broom.main(Broom.java:9)

Я знаю, что локальные переменные не инициализированы, и вы обязаны это сделать, но в этом случае первый if не инициализирует переменную?

Ответы [ 7 ]

14 голосов
/ 02 марта 2010

Если вы измените второе if на else, то компилятор будет счастлив.

int a = 1, b;
if(a > 0) b = 1;
else b = 2;
System.out.println(b);

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

правила не допускают изменения:

void flow(boolean flag) {
        int k;
        if (flag)
                k = 3;
        if (!flag)
                k = 4;
        System.out.println(k);  // k is not "definitely assigned" before here
}

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

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

5 голосов
/ 02 марта 2010

Сосредоточьтесь на «IF», ​​компилятор не может определить, будет ли условие выполнено.

3 голосов
/ 02 марта 2010

Пожалуйста, не пытайтесь запустить свой код, даже если он даже не компилируется.

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

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

Важным шагом является изучение различий между ошибками компилятора и исключениями времени выполнения.

2 голосов
/ 02 марта 2010

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

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

Из Java документы :

Локальной переменной (§14.4, §14.13) должно быть явно задано значение перед ее использованием, либо путем инициализации (§14.4), либо путем присваивания (§15.26) таким образом, который может быть проверен компилятором с помощью правила для определенного задания

1 голос
/ 02 марта 2010

Компилятор Java не может обнаружить, что другой if работает как else. Компиляторы умны, но не настолько умны.

1 голос
/ 02 марта 2010

Локальные переменные не заменяются во время компиляции, поэтому компилятор не имеет представления, является ли IF истинным или ложным.

С другой стороны, если переменная была определена final, то она будет заменена во время компиляции.

0 голосов
/ 02 марта 2010

Вы можете добавить ключевое слово final в объявление a, чтобы помочь вашему компилятору оптимизировать код.

// this compiles just fine
final int a = 1, b;
if(a > 0) b = 1;
if(a <= 0) b = 2;
System.out.println(b);
...