web-dev-qa-db-fra.com

Si les déclarations vides

Par "instruction if vide", j'entends quelque chose comme ceci (notez le point-virgule):

if (condition);

J'ai du mal à penser à une application pour cela. Avec une boucle while, vous pouvez faire ceci:

while (callUntilReturnsFalse());

Mais il n'y a pas une telle application pour une instruction if. De plus, le compilateur Java ne génère pas d'erreur ni d'avertissement lorsqu'il est confronté à une telle déclaration. Cela peut entraîner de gros problèmes et silence, en particulier avec une déclaration longue et compliquée:

if ((functionA() && functionB(getFoo()) ||
    checkForComplexCondition(arg1, arg2, getBar(getFoo())));
{
    doStuff();
}

Ma question est: pourquoi est-ce autorisé en Java? Et, plus important encore, puis-je activer une option pour générer un avertissement lorsque cela se produit?

(Cette question était posée auparavant en ce qui concerne C #, ce qui envoie un avertissement, mais j'espérais trouver un moyen de provoquer un avertissement avec Java.)

23
nullptr

pourquoi est-ce autorisé en Java?

Voir Spécifications du langage Java (14.6. L'instruction vide) :

Une déclaration vide ne fait rien.

C'est simplement permis et c'est équivalent à (et sera traduit en):

if (condition) {  }

Ce qui signifie que si la condition est vraie, ne faites rien.

Si vous utilisez Eclipse, vous pouvez chercher ici, vous trouverez peut-être quelque chose d'utile (je ne suis pas sûr qu'il existe une telle option pour le point-virgule)

FenêtrePréférencesJavaCompilateurErreur/Avertissements

enter image description here


MODIFIER

Comme @nullptr l'a souligné dans sa réponse, il existe un avertissement IDE pour cela, vous devez définir warning sur déclaration vide.

14
Maroun

Je ne pense pas que cela soit vraiment pertinent par rapport à l'objet de la question, mais je pense que cela devrait être indiqué, car cela est pertinent pour l'essence de la question.

Il est un effet d'un:

if(variable);

si la variable est volatile. Son effet est de faire respecter une barrière de mémoire entre le thread actuel et tous les autres threads accédant à la variable.

public volatile variable;
....
if(variable);

Voir ici pour une discussion plus détaillée.

Je ne peux pas imaginer la valeur réelle de ce type d’énoncé dans votre code, mais j’ai jugé important de noter que cet énoncé a un effet réel dans cette situation très spécifique.

13
OldCurmudgeon

Il y a une construction que j'utilise assez souvent et que "l'instruction nulle" rend plus claire et plus facile à comprendre. Voici un exemple:

for (int i=0;  i < argc;  i++)
{
   if (argv[i]=="left")
      hpos++;
   else if (argv[i]=="right")
      hpos--;
   else if (argv[i]=="up")
      ;
   else if (arv[i]=="down")
      ;
   else fprintf(stderr, "Unknown option \"%s\\n".", argv[i]);
}

Dans ce cas, je veux toujours vérifier le existence de certaines options, tout en n’exécutant que du code pour certains d'eux. Dans ce cas, utiliser l'instruction null, comme ci-dessus, rend la fonction et la structure du code plus lisibles et compréhensibles par le prochain utilisateur qui doit le gérer et le maintenir. 

Il existe certainement des moyens de restructurer ce code pour ne pas requérir l'instruction null. Mais je ne crois pas que son intention sera aussi claire que dans l'extrait de code.

4
Curt

J'ai trouvé un avertissement à ce sujet dans Eclipse sous la forme Empty statement:

example

Merci à Maroun Maroun de m'avoir mis sur la bonne voie.

2
nullptr

Je ne vois pas tant de danger dans la possibilité d'une if avec une déclaration vide. La logique qui la sous-tend réside dans la grammaire du langage Java, qui autorise l’instruction vide ;:

Block: 
    { BlockStatements }

BlockStatements: 
    { BlockStatement }

BlockStatement:
    LocalVariableDeclarationStatement
    ClassOrInterfaceDeclaration
    [Identifier :] Statement

LocalVariableDeclarationStatement:
    { VariableModifier }  Type VariableDeclarators ;

Statement:
    Block
    ;
    Identifier : Statement
    StatementExpression ;
    if ParExpression Statement [else Statement] 
    assert Expression [: Expression] ;
    switch ParExpression { SwitchBlockStatementGroups } 
    while ParExpression Statement
    do Statement while ParExpression ;
    for ( ForControl ) Statement
    break [Identifier] ;
    continue [Identifier] ;
    return [Expression] ;
    throw Expression ;
    synchronized ParExpression Block
    try Block (Catches | [Catches] Finally)
    try ResourceSpecification Block [Catches] [Finally]

Notez que cela est vrai pour presque toutes les langues impératives .

Je veux dire que cela peut être dangereux et difficile à trouver, comme tous les autres corps vides au cas où vous oublieriez une implémentation, certainement rien pour lequel je perdrais le sommeil. Dans une instruction longue et compliquée, vous pourriez avoir des problèmes à cause d'un ( ) qui ferme la mauvaise paire d'expressions ou même si vous pensez que votre condition est mauvaise (en particulier avec plusieurs && et ||).

2
Jack

La condition pourrait être un appel de fonction avec des effets secondaires. Ce ne serait pas correct de le traiter comme une erreur ou un avertissement.

1
user207421

Je suis principalement un développeur C #, même si j'ai un peu de connaissances en Java. Mais je pense que ma réponse s'applique aux deux. Je soupçonne que ce n'est pas une fonctionnalité intentionnelle, mais plutôt une fonctionnalité émergente. La grammaire de la langue va (à peu près)

if (*condition*)
    *statement*

Malheureusement, les deux énoncés ci-dessous sont valides (j'ai vérifié, vous pouvez en déposer autant que vous voulez en C # et le compilateur ne se plaint pas):

;

{
}

Par conséquent, la construction que vous avez surlignée est autorisée.

1
David Cummins

Je crois qu'ils l'ont laissé parce que cela peut augmenter la lisibilité du code. Même si rien ne doit être fait pour un cas, vous pouvez quand même vouloir faire savoir aux gens que le cas est important. 

0
aaronman

La plupart des compilateurs Java ne font aucune optimisation du code. Ils délèguent ce travail pendant l'exécution à Java Runtime Environment. La JVM vérifie le code avant son exécution, mais cette vérification consiste principalement en trois vérifications:

  1. Branches dans valide positions (différent de correct).
  2. Les données sont toujours initialisées et les références toujours sécurisées.
  3. L'accès aux données privées est contrôlé.

Ainsi, votre instruction if peut être faux, mais elle est toujours valide. Aussi valide que

 if (a==a)
0
Asier Aranbarri

Dans la déclaration

if  (eval) { //pseudo-code
}

Parfois, les données sont réellement modifiées lors de l'évaluation de (eval). Par exemple, dans

while (someIterator.next()) {
}

L'appel de next () modifie en réalité l'état de l'objet someIterator.

Et bien sûr, il y a l'exemple classique qui se produit généralement à partir d'une faute de frappe (et n'est pas recommandé)

int x;  
if (x = getNumberOfWidgets() > 5) {
}

La sagesse conventionnelle déconseille de coder de cette façon, car il est plus difficile de dire ce qui se passe. Cependant, les déclarations sont légales et c'est donc l'une des raisons pour lesquelles une telle déclaration "si" est autorisée. 

0
user1445967