Pourquoi cette instruction if, avec une affectation et un contrôle d'égalité, est-elle évaluée à false?

105

Comment fonctionne une instruction Java if lorsqu'elle a une affectation et une vérification d'égalité OR-d ensemble?

public static void test() {
    boolean test1 = true; 
    if (test1 = false || test1 == false) {
        System.out.println("TRUE");
    } else {
        System.out.println("FALSE");
    }       
}

Pourquoi cette impression est-elle FAUX?

RoHaN
la source
1
Exécutez et vérifiez. Voyez quelle valeur booléenne est affichée si vous affectez false et si vous affectez true. Ensuite, lisez comment fonctionne OR.
Pratik
2
Je voudrais dire que ce code en mode débogage donne une valeur TRUE et en mode Running donne une valeur FALSE ... Pourquoi il en est ainsi ??? ... (je mets mon point d'arrêt sur si condition) ...
CoderNeji
test1=false, test1==falseest false, false || falseest false or falsequi est false.
Jared Burrows
Je sais que vous ne demandiez pas de conseils, mais comme les réponses ci-dessous identifient un problème de priorité, voici quelques pratiques qui m'ont aidé à éviter les problèmes (quand je m'en tiens à celles-ci): (1) utilisez toujours des parenthèses quand ce n'est pas à 100% certain de priorité ou pour une lisibilité plus facile pour aider d'autres développeurs. Ne supposez pas que les autres se souviendront des règles de priorité pour tous les opérateurs (2) les affectations if devraient généralement être évitées pour réduire la confusion, sauf pour des conditions if très simples. Il existe quelques exceptions courantes (en particulier avec de simples vérifications d'E / S, de mise en réseau, etc.). Juste mes deux cents.
rimsky
parce quetest1 = true
jono

Réponses:

189

L'expression n'est pas analysée comme vous le pensez. Ce n'est pas

(test1=false) || (test1 == false)

auquel cas le résultat aurait été true, mais

test1 = (false || test1 == false)

La valeur de l' false || test1 == falseexpression est calculée en premier, et c'est le cas false, car elle test1est définie pour trueentrer dans le calcul.

La raison pour laquelle il est analysé de cette façon est que la priorité du ||est inférieur à celui de l' ==opérateur, mais supérieur à la priorité de l'opérateur d'affectation =.

dasblinkenlight
la source
2
+1 @RohanFernando, veuillez également noter que si vous ajoutiez des crochets autour de l'affectation comme ceci: ((test1 = false) || test1 == false)la valeur globale serait true.
Arnon Zilca
1
Veuillez écrire la raison pour laquelle l'analyse se produit ainsi ... Est-ce à cause de l'ordre de priorité des opérateurs?
kondu
3
@kondu C'est une question de suivi juste, j'ai édité pour ajouter un lien vers une table de priorité, qui montre que ==c'est au-dessus ||, mais en =dessous ||.
dasblinkenlight
Le dernier paragraphe est trompeur, en ce sens que pour comprendre pourquoi la seconde analyse est choisie plutôt que la première, il suffit de connaître la règle (facile à retenir) selon laquelle l'affectation a une priorité inférieure à tout opérateur de non-affectation (ici ||). La priorité relative de ||et ==ne concerne que pour montrer que l' analyse syntaxique est pas comme dans test1 = ((false || test1) == false), que je ne pense pas que quiconque peut raisonnablement s'attendre (par la façon dont la priorité relative, ou plus généralement ||, &&ont une priorité plus faible que les relations, est aussi facile à rappelez-vous, depuis utilisé tout le temps).
Marc van Leeuwen
1
@MarcvanLeeuwen La précédence relative de ||et ==vs ||et =explique pourquoi cela se comporte différemment du cas (courant) de a == b || c == d.
Aaron Dufour
83

Il s'agit essentiellement d'une question de priorité. Vous supposez que votre code équivaut à:

if ((test1 = false) || (test1 == false))

... mais ce n'est pas. C'est en fait équivalent à:

if (test1 = (false || test1 == false))

... ce qui équivaut à:

if (test1 = (false || false))

(parce que test1c'esttrue pour commencer)

... ce qui équivaut à:

if (test1 = false)

qui affecte la valeur falseà test1, le résultat de l'expression étantfalse .

Consultez le didacticiel Java sur les opérateurs pour un tableau utile de la priorité des opérateurs.

Jon Skeet
la source
2

veuillez jeter un œil à la priorité des opérateurs

Expression test1 = false || test1 == false sera évaluée à l'étape suivante.

ÉTAPE: 1- test1 = false || test1 == false // priorité de== est la plus élevée

ÉTAPE: 2- test1 = false || false // Opérateur|| ont une priorité plus élevée

ÉTAPE 3- test1 = false

ÉTAPE 4- false

Puisque la valeur booléenne de l'expression devient fausse, l'instruction So else est en cours d'exécution.


la source
-11

(test1 = false || test1 == false)renvoie false, car les deux sont faux. (test1 = false || test1 == true)c'est vrai parce que l'un d'eux est vrai

Tanière
la source
1
Totalement faux. Pourquoi répondriez-vous avec des informations aussi incorrectes quelques jours après que la question ait reçu deux réponses de haute qualité qui décrivent ce qui se passe?
l4mpi
5
Deux réponses d'une qualité aussi médiocre ne méritent pas de commentaires écrits individuellement. Vous réalisez que votre réponse est absurde, non? Sinon, lisez attentivement les deux réponses de Jon et blinkenlight.
l4mpi