Через тест я узнал, что
Это не является законным:
for (int i= 0; i < 1000000000; i++)
int j = i & i+1 ; // j cannot be declared here!
но это:
for (int i= 0; i < 1000000000; i++) {
int j = i & i+1 ;
}
Почему?
Через тест я узнал, что
Это не является законным:
for (int i= 0; i < 1000000000; i++)
int j = i & i+1 ; // j cannot be declared here!
но это:
for (int i= 0; i < 1000000000; i++) {
int j = i & i+1 ;
}
Почему?
Первый способ не является законным, так как для компилятора ясно, что вы не можете использовать j
, который вы там указали, поскольку в этом цикле for
не может быть другого оператора. В основном новое объявление переменной в этом месте выходит за рамки самого следующего утверждения, поэтому ничего хорошего не делает.
Во втором случае за циклом следуют фигурные скобки, которые создают новую область, и вы можете использовать переменную.
Локальное объявление переменной должно быть в блоке. В первом случае у вас его нет в блоке. Во втором случае j
находится внутри блока, поэтому он является законным.
Локальное объявление переменных не является оператором, это выражение о локальном переменном. Из приведенной ниже ссылки локальное объявление переменной может отображаться только как оператор внутри блока. (Блок представляет собой пару фигурных скобок, содержащих утверждения и декларации.)
for (int i= 0; i < 1000000000; i++)
int j = i & i+1 ; // Local variable j declaration not within a block ==> ERROR
for (int i= 0; i < 1000000000; i++) {
int j = i & i+1 ; // Local variable j declaration within a block ==> NO ERROR
}
Цитата из 14.4. Локальные заявления о декларации переменных:
...
Каждый оператор объявления локальной переменной немедленно содержится в блок. Операторы объявления локальной переменной могут быть перемешаны свободно с другими видами операторов в блоке.
...
И из 14.2. Блоки:
Блок представляет собой последовательность операторов, локальных деклараций классов и локальные инструкции объявления переменных в фигурных скобках.
Block: { BlockStatementsopt } BlockStatements: BlockStatement BlockStatements BlockStatement BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement
Блок выполняется путем выполнения каждой локальной переменной заявления декларации и другие заявления для последний (слева направо). Если все эти инструкции блока завершены обычно, тогда блок завершается нормально. Если какой-либо из этих блоков операторы завершаются по какой-либо причине, то блок завершается по той же причине.
Кроме того, это поведение не ограничивается Java. Вы заметили бы ошибку в подобной ситуации даже в C:
for(int i=0; i<=100; i++)
int j = i; /* Error: error: expected expression before 'int' */
for(int i=0; i<=100; i++) {
int j = i; /* Perfect */
}
Локальное объявление переменных не допускается как один оператор для любой из грамматических конструкций, которые позволяют использовать один оператор вместо блока. Итак for
, while
, if
и т.д.
Как он сломается (немного перефразированный), у вас есть for
statement:
for (...;...;...) Statement
Блок
ExpressionStatement
An ExpressionStatement
- это то, что вы можете использовать, когда у вас есть только один оператор, но LocalVariableDeclarationStatement
- это BlockStatement
.
Как заметил @RohitJain, было бы особенно полезно иметь только объявление переменной как единый оператор цикла.