Pull to refresh

Будни программиста или редкий случай ошибки в компиляторе

Reading time1 min
Views1.7K
Имеем следующий код:

1    class A {
2        
3     private B line;
4   
5     public void foo() {
6       for (Integer line : line.getElements()) {
7    
8       }
9     }
10    }
11    
12    class B {
13    
14      List<Integer> getElements() {
15         return null; // doesn't matter
16      }
17    }


Вопрос: скомпилируется ли код?
Ответ: должен, но не будет



А теперь объясняем почему.

Понятно, что в строке 6 происходит затемнение(eclipsing) поля класса переменной цикла. Но, по спецификации это не так! Самое смешное, что одна популярная платная IDE для Java ведет себя правильно, а компилятор жалуется, что getElements() отсутствует у line.

Читаем спецификацию:

The enhanced for statement has the form:

EnhancedForStatement:
for ( VariableModifiersopt Type Identifier: Expression) Statement
The Expression must either have type Iterable or else it must be of an array type (§10.1), or a compile-time error occurs.
The scope of a local variable declared in the FormalParameter part of an enhanced for statement (§14.14) is the contained Statement


Для тех, кому лень читать по-английски:

for ( VariableModifiersopt Type Identifier: Expression) Statement



Область видимости локальной переменной, объявляемой в Identifier, распространяется на Statement. Т.е. на Expression не распространяется.

Таким образом, затемнения поля здесь происходить не должно, но происходит. Засабмичен баг на эту тему под номером 7139681, но он появится в публичном доступе лишь через пару дней.

Будьте внимательны!

P.S. Я задал соответсвующий вопрос на SO, ждем обновлений.

P.P.S. Java 1.6.0.26 64bit
Tags:
Hubs:
Total votes 50: ↑42 and ↓8+34
Comments21

Articles