57 votes

Accolades dans la condition if en Java

Pourquoi ce premier if bien compilé et le second échoue?

 if(proceed) {int i;} // This compiles fine.
if(proceed) int i;// This gives an error. (Syntax error on token ")", { expected after this token)
 

72voto

Brian Roach Points 43787

Parce que la langue spec dit:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html

Une déclaration introduit une entité dans un programme et comprend un identificateur (§3.8) qui peuvent être utilisés dans un nom pour désigner cette entité. Une déclaration de l'entité est l'un des suivants:
...
Une variable locale, l'une des opérations suivantes:
* Une variable locale déclarée dans un bloc (§14.4)
* Une variable locale déclarée dans le cadre d'une instruction (§14.14)

Votre premier exemple est de déclarer i à l'intérieur d'un bloc (notée par des accolades). Votre deuxième ne l'est pas, ni est-il un for déclaration.

Edité pour ajouter: ce Qui rend juste les communes de sens. Si elle était admise, il serait inutile. Il serait immédiatement compris hors de portée.

53voto

Daniel Points 13823

À partir du Langage Java Spec.

    Bloc:
 { BlockStatementsopt}

 BlockStatements:
 BlockStatement
 BlockStatements BlockStatement

 BlockStatement:
 LocalVariableDeclarationStatement
 ClassDeclaration
 Déclaration

et

IfThenStatement:
 if ( Expression ) Instruction

Il semble qu' int i est LocalVariableDeclarationStatement, pas un Statement. Si cela ne fonctionne pas.

12voto

steffinchen Points 436

C'est parce que ce ne serait pas un code utile. Si vous avez une instruction if sans accolades ({}), seule la première ligne / instruction après le if est exécutée. Donc, si vous ne déclarez qu'une variable locale, elle ne peut être utilisée nulle part ailleurs. Donc, le déclarer est absolument superflu.

 if(proceed){
int i= 0;
 // variable i can be used here
//...
}

if (proceed) int i; // i can not be used anywhere as it is a local variable
 

3voto

si () int i;

Si nous utilisons if déclaration sans accolades, il s'exécute uniquement la première ligne avec l' if pour la manière conditionnelle. D'autres lignes s'exécuter normalement.

C'est la compilation échoue, parce que la déclaration de variable locale arriver avec la manière conditionnelle et le compilateur suppose que c'est pas accessible avec la fausse déclaration.

Si vous utilisez un des accolades, alors la déclaration de la variable et l'utilisation de variables locales dans le bloc et donc le compilateur suppose que c'est accessible code. Alors pas d'erreurs du compilateur.

2voto

alfasin Points 19063

Le JLS (§14.5) est un peu compliqué mais c'est aussi très terminologie exacte qui l'explique:

Tout d'abord, il est dit qu'après un if (appelé: IfThenStatement), nous pouvons avoir seulement statement:

IfThenStatement:
    if ( Expression ) Statement

mais maintenant, nous devons regarder dans la définition de l' statement qui devient un peu plus compliqué:

Statement:
    StatementWithoutTrailingSubstatement
    LabeledStatement
    IfThenStatement
    IfThenElseStatement
    WhileStatement
    ForStatement

StatementWithoutTrailingSubstatement:
    Block
    EmptyStatement
    ExpressionStatement
    AssertStatement
    SwitchStatement
    DoStatement
    BreakStatement
    ContinueStatement
    ReturnStatement
    SynchronizedStatement
    ThrowStatement
    TryStatement

StatementNoShortIf:
    StatementWithoutTrailingSubstatement
    LabeledStatementNoShortIf
    IfThenElseStatementNoShortIf
    WhileStatementNoShortIf
    ForStatementNoShortIf

comme nous pouvons le voir - c'est un appel récursif à la déclaration, et certaines expressions qui apparaissent sur cette définition sont définies de manière récursive ailleurs. Nous suivons le chemin qui nous intéresse:

StatementWithoutTrailingSubstatement --> ExpressionStatement 

Maintenant, l'Expression des États sont définis plus bas dans JLS §14.5 comme suit:

ExpressionStatement:
    StatementExpression ;

StatementExpression:
    Assignment
    PreIncrementExpression
    PreDecrementExpression
    PostIncrementExpression
    PostDecrementExpression
    MethodInvocation
    ClassInstanceCreationExpression

et nous avons finalement obtenu:

ExpressionStatement --> StatementExpression --> Assignment

maintenant, nous n'avons qu'une partie manquante, la déclaration, ou à l'aide de la JLS nom: LocalVariableDeclarationStatement qui est défini dans JLS §14.4:

LocalVariableDeclarationStatement:
    LocalVariableDeclaration ;

LocalVariableDeclaration:
    VariableModifiersopt Type VariableDeclarators

alors maintenant que nous avons constaté que, d'autre part, nous avons besoin de remonter à l'origine de la définition de l' Statement, et en effet, dans JLS §14.2 , nous pouvons le trouver "masquage" de manière récursive, en vertu de la définition de l' block statements:

Block:
    { BlockStatementsopt }

BlockStatements:
    BlockStatement
    BlockStatements BlockStatement

BlockStatement:
    LocalVariableDeclarationStatement
    ClassDeclaration
    Statement

Voilà, nous avons maintenant les deux extrémités attachées. Si nous revenons en arrière, au début de cette exploration, nous pouvons voir que, en vertu de l' statement definition nous avons eu:

Statement --> StatementWithoutTrailingSubstatement --> ExpressionStatement 
                        |
                        --> block --> BlockStatements --> BlockStatement --> LocalVariableDeclarationStatement

depuis les deux ExpressionStatement et LocalVariableDeclarationStatement sont statements, et qu' un énoncé peut suivre, IfThenStatement, la ligne:

int ans = x + y;

va à l'encontre de JLS règles et donc génère une erreur de compilation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X