Java boolean
autorise les valeurs de true
et false
alors que Boolean autorise true
, false
et null
. J'ai commencé à convertir mes boolean
s en Boolean
s. Cela peut provoquer des plantages lors de tests tels que
Boolean set = null;
...
if (set) ...
pendant que le test
if (set != null && set) ...
semble artificiel et sujet aux erreurs.
À quel moment est-il utile d'utiliser Boolean
s avec des valeurs NULL? Si jamais, quels sont les principaux avantages de l'objet enveloppé?
MISE À JOUR: Il y a eu tellement de réponses intéressantes que j'en ai résumé certaines dans ma propre réponse. Au mieux, je suis un intermédiaire dans Java et j’ai donc essayé de montrer ce que je trouve utile. Notez que la question est "mal formulée" (la valeur booléenne ne peut pas "avoir une valeur nulle") mais je l'ai laissée au cas où d'autres auraient la même idée fausse.
Utilisez boolean
plutôt que Boolean
chaque fois que vous le pouvez. Cela évitera beaucoup de NullPointerException
s et rendra votre code plus robuste.
Boolean
est utile, par exemple
MessageFormat.format()
.Je n'utilise presque jamais Boolean
parce que sa sémantique est vague et obscure. En gros, vous avez une logique à 3 états: vrai, faux ou inconnu. Parfois, il est utile de l’utiliser lorsque, par exemple, vous avez donné à l'utilisateur le choix entre deux valeurs et l'utilisateur n'a pas répondu du tout et vous voulez vraiment connaître cette information (pensez: colonne de la base de données NULLable).
Je ne vois aucune raison de convertir de boolean
à Boolean
car cela introduit une surcharge de mémoire, une possibilité NPE et moins de dactylographie. En général, j'utilise maladroitement BooleanUtils.isTrue()
pour me rendre la vie un peu plus facile avec Boolean
.
La seule raison de l'existence de Boolean
est la possibilité d'avoir des collections de type Boolean
(les génériques n'autorisent pas boolean
, ainsi que toutes les autres primitives).
Wow, quoi sur terre? Est-ce juste moi ou est-ce que toutes ces réponses sont fausses ou du moins trompeuses?
La classe Boolean est une enveloppe autour du type primitif booléen. L'utilisation de ce wrapper est de pouvoir passer un booléen dans une méthode qui accepte un objet ou un générique. C'est à dire vecteur.
Un objet booléen ne peut JAMAIS avoir la valeur null. Si votre référence à un booléen est null, cela signifie simplement que votre booléen n'a jamais été créé.
Vous pourriez trouver cela utile: http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/6-b14/Java/lang/Boolean.Java
Une référence booléenne null ne doit être utilisée que pour déclencher une logique similaire à laquelle vous avez une autre référence null. Son utilisation pour une logique à trois états est maladroite.
EDIT: notez que Boolean a = true;
est une déclaration trompeuse. Ceci équivaut vraiment à quelque chose de plus proche de Boolean a = new Boolean(true);
S'il vous plaît voir la sélection automatique de code ici: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing
C’est peut-être de là que vient en grande partie la confusion.
EDIT2: S'il vous plaît lire les commentaires ci-dessous. Si quelqu'un a une idée de la façon de restructurer ma réponse pour l'incorporer, veuillez le faire.
Il y a trois raisons rapides:
true
, false
ou null
xsd:boolean
du schéma XML déclarées avec xsd:nillable="true"
List<Boolean>
- vous ne pouvez pas utiliser List<boolean>
RÉPONSE À SA PROPRE QUESTION: Je pensais qu'il serait utile de répondre à ma propre question car j'ai beaucoup appris des réponses. Cette réponse est destinée à aider ceux qui, comme moi, ne comprennent pas parfaitement les problèmes. Si j'utilise un langage incorrect, corrigez-moi.
true
et false
. C'est l'absence d'un pointeur sur les objets. Par conséquent, penser que le booléen a une valeur de 3 est fondamentalement fauxLa syntaxe de Boolean est abrégée et masque le fait que la référence pointe sur Objets:
Boolean a = true;
dissimule le fait que true
est un objet. D'autres tâches équivalentes pourraient être:
Boolean a = Boolean.TRUE;
ou
Boolean a = new Boolean(true);
La syntaxe abrégée
if (a) ...
diffère de la plupart des autres assignations et dissimule le fait qu’il peut s’agir d’une référence d’objet ou d’une primitive. Si un objet, il est nécessaire de tester null
pour éviter NPE. Pour moi, il est psychologiquement plus facile de s'en souvenir s'il existe un test d'égalité:
if (a == true) ...
où nous pourrions être invités à tester pour null. La forme abrégée n'est donc sûre que lorsque a
est une primitive.
Pour moi, j'ai maintenant les recommandations:
Boolean
depuis une méthode car il pourrait s'agir de null
. Ne retourne que boolean
.Boolean
pour encapsuler des éléments dans des conteneurs ou des arguments de méthodes lorsque des objets sont requis.Les classes wrapper pour les primitives peuvent être utilisées lorsque des objets sont requis, les collections sont un bon exemple.
Imaginez que vous ayez besoin, pour une raison quelconque, de stocker une séquence de boolean
dans un ArrayList
, ceci peut être effectué en encadrant boolean
dans Boolean
.
Il y a quelques mots à ce sujet ici
De la documentation:
Comme tout programmeur Java, vous ne pouvez pas insérer un int (ou une autre valeur primitive) dans une collection. Les collections ne pouvant contenir que des références d’objet, vous devez donc encadrer les valeurs primitives dans la classe d’encapsuleur appropriée (Integer dans le cas de int). Lorsque vous retirez l'objet de la collection, vous obtenez le nombre entier que vous avez inséré; si vous avez besoin d'un int, vous devez décompresser l'integer à l'aide de la méthode intValue. Toutes ces opérations de boxe et de déballage sont pénibles et encombrent votre code. La fonctionnalité de sélection automatique et unboxing automatise le processus en éliminant la douleur et l'encombrement.
http://docs.Oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
Je suppose que dans certains cas, vous devriez avoir un mécanisme pour distinguer un champ booléen qui définit déjà une valeur ou non.
Le wrapper Boolean
est utile lorsque vous souhaitez indiquer si une valeur a été affectée ou non en dehors de true
et false
. Il a les trois états suivants:
null
Alors que boolean
n'a que deux états:
La différence ci-dessus le rendra utile dans les listes de valeurs Boolean
pouvant contenir True
, False
ou Null
.
Pour toutes les bonnes réponses ci-dessus, je vais simplement donner un exemple concret dans la classe Java servlet HttpSession
. J'espère que cet exemple aidera à clarifier une question que vous pourriez encore avoir.
Si vous devez stocker et récupérer des valeurs pour une session, utilisez la méthode setAttribute
(String, Object) et getAttribute
(String, Object). Donc, pour une valeur booléenne, vous êtes obligé d'utiliser la classe Boolean si vous souhaitez la stocker dans une session http.
HttpSession sess = request.getSession(false);
Boolean isAdmin = (Boolean) sess.getAttribute("admin");
if (! isAdmin) ...
La dernière ligne provoquera un NullPointerException
si les valeurs d'attribut ne sont pas définies. (ce qui est la raison qui m'a amené à ce post). Donc, l'état logique est là pour rester, que vous préfériez l'utiliser ou non.
Boolean peut être très utile lorsque vous avez besoin de trois états. Comme dans les tests de logiciel, si Test est passé, envoyez true, en cas d'échec, envoyez false et si le test élémentaire est interrompu, envoyez null, ce qui indiquera que le test élémentaire n'a pas été exécuté.
Il y a beaucoup d'utilisations à la valeur ** null ** dans le wrapper booléen! :)
Par exemple, vous pouvez avoir dans un formulaire un champ nommé "newsletter" qui indique si l'utilisateur souhaite ou non une newsletter de votre site. Si l'utilisateur ne sélectionne pas de valeur dans ce champ, vous pouvez implémenter un comportement par défaut pour cette situation (envoyer? Ne pas envoyer?, Question à nouveau?, Etc.). Clairement, non défini (ou non sélectionné ou ** null **), n’est pas le même que vrai ou faux.
Mais si "non défini" ne s'applique pas à votre modèle, ne changez pas la primitive booléenne;)
Dans une définition stricte d'un élément booléen, il n'y a que deux valeurs. Dans un monde parfait, ce serait vrai. Dans le monde réel, l'élément peut être manquant ou inconnu. En règle générale, cela implique une intervention de l'utilisateur. Dans un système basé sur un écran, cela pourrait être forcé par une édition. Dans un monde par lots utilisant une base de données ou une entrée XML, l'élément peut facilement être manquant.
Ainsi, dans le monde non parfait dans lequel nous vivons, l'objet booléen est génial dans la mesure où il peut représenter l'état manquant ou inconnu comme nul. Après tout, les ordinateurs ne font que modéliser le monde réel et devraient prendre en compte tous les états possibles et les gérer avec des exceptions de projection (principalement dans la mesure où il existe des cas où le lancement de l'exception constituerait la réponse correcte).
Dans mon cas, l'objet booléen était la réponse idéale, car l'élément XML manquait parfois et je pouvais toujours obtenir une valeur, l'attribuer à un booléen, puis rechercher la valeur null avant d'essayer d'utiliser un test vrai ou faux. .
Juste mes 2 cents.
Le but principal du booléen est une valeur nulle. La valeur NULL indique que cette propriété n'est pas définie, par exemple, prenez la colonne Nullable de la base de données.
Si vous avez vraiment besoin de convertir tout ce qui est booléen primitif en un booléen wrapper, vous pouvez utiliser ce qui suit pour prendre en charge l'ancien code:
Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...
Le meilleur moyen serait d'éviter complètement les booléens, car chaque booléen implique que vous ayez une instruction conditionnelle n'importe où dans votre code (voir http://www.antiifcampaign.com/ et cette question: - Pouvez-vous écrire un algorithme sans une instruction if? ).
Cependant, de manière pragmatique, vous devez utiliser des booléens de temps en temps, mais, comme vous l'avez déjà constaté vous-même, traiter avec des booléens est plus sujet aux erreurs et plus lourd. Je suggère donc d'utiliser des booléens dans la mesure du possible. Les exceptions à cette règle peuvent être une base de données héritée avec des colonnes booléennes pouvant être annulées, bien que j'essaie également de cacher cela dans mon mappage.