93 votes

Pourquoi Java n'a-t-il pas de version d'assignation composée des opérateurs conditionnel et et conditionnel ou? (&& =, || =)

Donc, pour les opérateurs binaires sur les booléens, Java a &, |, ^, && et ||.

Résumons ce qu'ils font ici brièvement:

Pour &, la valeur du résultat est true si les deux opérandes de l'valeurs sont true; sinon, le résultat est false.

Pour |, la valeur du résultat est false si les deux opérandes de l'valeurs sont false; sinon, le résultat est true.

Pour ^, la valeur du résultat est true si l'opérande valeurs sont différentes, sinon, le résultat est false.

L' && opérateur est comme & mais évalue sa droite opérande seulement si la valeur de sa main gauche opérande est - true.

L' || opérateur est comme |, mais évalue sa droite opérande seulement si la valeur de sa main gauche opérande est - false.

Or, parmi tous les 5, 3 de ceux qui ont composé l'affectation des versions, à savoir l' |=, &= et ^=. Donc ma question est évidente: pourquoi ne pas Java fournissent &&= et ||= ? Je trouve que j'ai besoin de ces plus que je besoin d' &= et |=.

Et je ne pense pas que "parce que c'est trop long" est une bonne réponse, parce que Java a >>>=. Il doit y avoir une meilleure raison de cette omission.


De 15.26 Opérateurs D'Affectation:

Il y a 12 opérateurs d'affectation; [...] = *= /= %= += -= <<= >>= >>>= &= ^= |=


Un commentaire a été fait que si &&= et ||= ont été mises en œuvre, alors il serait le seul des opérateurs qui ne sont pas d'évaluer le côté droit en premier. Je crois que cette notion que l'opérateur d'assignation composé évalue le côté droit de la première est une erreur.

De 15.26.2 Composé Des Opérateurs D'Affectation:

Un composé expression d'affectation de la forme E1 op= E2 est équivalent à E1 = (T)((E1) op (E2))T est le type d' E1, sauf qu' E1 est évaluée qu'une seule fois.

Pour preuve, l'extrait de code suivant renvoie une NullPointerException, pas un ArrayIndexOutOfBoundsException.

    int[] a = null;
    int[] b = {};
    a[0] += b[-1];

32voto

olibre Points 6069

Raison

Les opérateurs &&= et ||= ne sont pas disponibles sur le C / C++ / Java parce que :

  • le risque d'erreur de
  • inutile

Exemple pour &&=

Si C ou C++ ou Java autorisés &&= de l'opérateur, alors que le code:

bool isOk = true; //becomes false when at least a function returns false
isOK &&= f1();
isOK &&= f2(); //we may expect f2() is called whatever the f1() returned value

est équivalent à:

bool isOk = true;
if (isOK) isOk = f1();
if (isOK) isOk = f2(); //f2() is called only when f1() returns true

Ce premier code est le risque d'erreur de parce que de nombreux développeurs penserait f2() est toujours appelé quelle que soit la f1() valeur renvoyée. C'est comme bool isOk = f1() && f2();f2() n'est appelé que lorsque f1() retours true.

Si le développeur veut f2() seulement lors de l' f1() retours true, donc le deuxième code ci-dessus est moins sujette aux erreurs.

Autre personne (le développeur veut f2() toujours être appelé), &= suffit:

Exemple pour &=

bool isOk = true;
isOK &= f1();
isOK &= f2(); //f2() always called whatever the f1() returned value

En outre, la machine doit exécuter ce code ci-dessus comme la suivante:

bool isOk = true;
if (!f1())  isOk = false;
if (!f2())  isOk = false;  //f2() always called

Comparer && et & résultats

Les résultats des opérateurs && et & le même lorsqu'il est appliqué sur des valeurs booléennes?

Nous allons vérifier en utilisant le code Java suivant:

public class qalcdo {

    public static void main (String[] args) {
        test (true,  true);
        test (true,  false);
        test (false, false);
        test (false, true);
    }

    private static void test (boolean a, boolean b) {
        System.out.println (counter++ +  ") a=" + a + " and b=" + b);
        System.out.println ("a && b = " + (a && b));
        System.out.println ("a & b = "  + (a & b));
        System.out.println ("======================");
    }

    private static int counter = 1;
}

Sortie:

1) a=true and b=true
a && b = true
a & b = true
======================
2) a=true and b=false
a && b = false
a & b = false
======================
3) a=false and b=false
a && b = false
a & b = false
======================
4) a=false and b=true
a && b = false
a & b = false
======================

Donc OUI on peut remplacer && par & pour les valeurs booléennes ;-)

Afin de mieux utiliser &= au lieu de &&=.

De même pour ||=

Mêmes raisons que pour l' &&=:
opérateur de |= est moins sujette aux erreurs qu' ||=.

Si un développeur veut f2() de ne pas être appelé lors de l' f1() retours true, puis je le conseil les alternatives suivantes:

// here a comment is required to explain that 
// f2() is not called when f1() returns false, and so on...
bool isOk = f1() || f2() || f3() || f4();

ou:

// here the following comments are not required 
// (the code is enough understandable)
bool isOk = false;
if (!isOK) isOk = f1();
if (!isOK) isOk = f2(); //f2() is not called when f1() returns false
if (!isOK) isOk = f3(); //f3() is not called when f1() or f2() return false
if (!isOK) isOk = f4(); //f4() is not called when ...

17voto

Josh Lee Points 53741

Probablement parce que quelque chose comme

 x = false;
x &&= someComplexExpression();
 

semble devoir attribuer à x et évaluer someComplexExpression() , mais le fait que l'évaluation repose sur la valeur de x n'apparaît pas clairement dans la syntaxe .

De plus, la syntaxe de Java étant basée sur le C, personne n’a jugé urgent d’ajouter ces opérateurs. De toute façon, vous seriez probablement mieux avec une déclaration if.

12voto

EFraim Points 7137

C'est comme ça en Java, parce que c'est comme ça en C.

Maintenant, la question de savoir pourquoi il en est ainsi dans C est que lorsque & & && sont devenus des opérateurs différents (parfois avant que C ne descende de B), la variété d'opérateurs & = a simplement été négligée.

Mais la deuxième partie de ma réponse ne dispose d'aucune source pour la sauvegarder.

6voto

Alex Barrett Points 7719

&& est un opérateur logique , & est un opérateur au niveau des bits . Ils font deux choses différentes. L'affectation des résultats de l'ancien à la gauche de l'opération a moins de sens que pour les opérations au niveau des bits.

4voto

Yishai Points 42417

L'un de Java original objectifs était d'être "Simple, Orienté Objet, et Familier." Appliquée à ce cas, et= est familier (C, C++ de les avoir et de familier dans ce contexte, signifie familier à quelqu'un qui connaît ces deux).

&&= ne serait pas familier, et il ne serait pas simple, dans le sens que la langue concepteurs ne cherchaient pas à penser à chaque opérateur qu'ils pourraient ajouter à la langue, donc moins d'extra opérateurs sont plus simples.

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