Booléen vs booléen en Java


195

Il y a des discussions autour de Integervs inten Java. La valeur par défaut de la première est nullalors que dans la seconde, elle l'est 0. Que diriez-vous Booleanvs boolean?

Une variable dans mon application peut avoir 0/ 1valeurs. Je voudrais utiliser boolean/ Booleanet je préfère ne pas utiliser int. Puis-je utiliser Boolean/ à la booleanplace?


2
Pour des raisons de conception du système, je choisirais Boolean car il a l'option "L'utilisateur n'a pas encore décidé" qui n'est ni égal à "vrai", ni "faux". J'utiliserais la primitive booléenne uniquement dans les cas si je suis sûr à 100% que les options vrai / faux sont suffisantes. Dans la base de données, l'option NULL est généralement disponible sans problème (ou en supprimant simplement les restrictions NOT NULL sur demande ultérieure)
CsBalazsHungary

2
Copie exacte de Quelle est la différence entre booléen et booléen en Java? (car GWT ne fait aucune différence).
Dan Dascalescu

Réponses:


270

Oui, vous pouvez utiliser Boolean/ à la booleanplace.

Le premier est Object et le second est de type primitif.

  • Le premier, vous obtiendrez plus de méthodes qui vous seront utiles.

  • Le second est bon marché compte tenu des dépenses de mémoire Le second vous fera économiser beaucoup plus de mémoire, alors allez-y

Maintenant, choisissez votre chemin.


70
Vous auriez pu formuler ceci comme "le second vous fera économiser beaucoup plus de mémoire, alors allez-y". Les méthodes utiles sur Boolean peuvent généralement être invoquées sans en avoir une instance.
DJClayworth

3
Tant que vous utilisez à la place Boolean.valueOf (valeur) de nouveau Boolean (valeur), la mémoire ne devrait pas être un problème.
Greg Case

2
car AsyncTask, vous ne pouvez utiliser qu'à la Booleanplace de boolean.
Raptor

98
Il convient de noter qu'un booléen a en fait 3 états ... true, falseet nullqu'un booléen a les 2 états logiques ( trueet false)
respectTheCode

14
Boolean is trillean :)
Topera

50

Boolean encapsule le type primitif booléen. Dans JDK 5 et versions ultérieures , Oracle (ou Sun avant Oracle les a achetés) a introduit l' autoboxing / unboxing , ce qui vous permet essentiellement de le faire

boolean result = Boolean.TRUE;

ou

Boolean result = true; 

Ce que fait essentiellement le compilateur,

Boolean result = Boolean.valueOf(true);

Donc, pour votre réponse, c'est OUI.


4
Remarque: vous ne pouvez pas toujours affecter en toute sécurité a Booleanà a boolean. Si votre Booleanest nullet que vous essayez de l'assigner à un boolean, il lancera un NullPointerExceptionau moment de l'exécution.
Duncan Luk

si Booleanune classe, alors pourquoi la valeur est toujours fausse même si j'ai changé la valeur d'une autre classe faisant référence à la même variable booléenne? quel est l'intérêt de cela Booleanalors si nous ne pouvons pas faire référence à partir de différentes classes d'instance / passer comme argument?
user924

trouvé une réponse, nous pouvons l'utiliser AtomicBooleanet la référencer à partir des classes de différence
user924

35

J'étends un peu les réponses fournies (car jusqu'à présent, elles se concentrent sur leur "propre" / terminologie artificielle se concentrant sur la programmation d'un langage particulier au lieu de prendre soin de la vue d'ensemble derrière la scène de la création des langages de programmation , en général, c'est-à-dire lorsque les choses comme les considérations de sécurité de type par rapport à la mémoire font la différence):

int n'est pas booléen

Considérer

    boolean bar = true;      
    System.out.printf("Bar is %b\n", bar);
    System.out.printf("Bar is %d\n", (bar)?1:0);
    int baz = 1;       
    System.out.printf("Baz is %d\n", baz);
    System.out.printf("Baz is %b\n", baz);

avec sortie

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

Le code Java sur la 3ème ligne (bar)?1:0illustre que la barre ( booléenne ) ne peut pas être implicitement convertie (castée) en int . Je soulève cette question non pas pour illustrer les détails de l'implémentation derrière JVM, mais pour souligner qu'en termes de considérations de bas niveau (comme la taille de la mémoire), il faut préférer les valeurs à la sécurité des types. Surtout si ce type de sécurité n'est pas vraiment / pleinement utilisé comme dans les types booléens où les contrôles sont effectués sous forme de

si value \ in {0,1}, transtypez en type booléen, sinon lève une exception.

Tout cela pour dire que {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. On dirait une exagération, non? La sécurité des types est vraiment importante dans les types définis par l'utilisateur, et non dans la conversion implicite des primitives (bien que les dernières soient incluses dans la première).

Les octets ne sont pas des types ou des bits

Notez qu'en mémoire, votre variable de la plage de {0,1} occupera toujours au moins un octet ou un mot (xbits selon la taille du registre) à moins que cela ne soit spécialement pris en charge (par exemple, bien emballé en mémoire - 8 "booléen" bits en 1 octet - d'avant en arrière).

En préférant la sécurité des types (comme pour mettre / envelopper des valeurs dans une boîte d'un type particulier) plutôt que des valeurs supplémentaires (par exemple en utilisant des décalages de bits ou de l'arithmétique), on choisit effectivement d'écrire moins de code plutôt que de gagner plus de mémoire. (D'un autre côté, on peut toujours définir un type d'utilisateur personnalisé qui facilitera toute la conversion ne valant pas que booléen).

mot-clé vs type

Enfin, votre question porte sur la comparaison du mot clé et du type . Je crois qu'il est important d'expliquer pourquoi ou comment vous obtiendrez exactement des performances en utilisant / préférant des mots clés ("marqués" comme primitifs ) par rapport aux types (classes composites normales définissables par l'utilisateur utilisant une autre classe de mots clés ) ou en d'autres termes

boolean foo = true;

contre.

Boolean foo = true;

La première "chose" (type) ne peut pas être étendue (sous-classée) et non sans raison. Terminologie Java efficace de la primitive classes et enveloppantes peut être simplement traduite en valeur en ligne (un LITERAL ou une constante qui est directement substituée par le compilateur chaque fois qu'il est possible d'inférer la substitution ou sinon - toujours de retour dans l'encapsulation de la valeur).

L'optimisation est obtenue en raison de trivial:

"Moins d'opérations de casting à l'exécution => plus de vitesse."

C'est pourquoi, lorsque l'inférence de type réelle est effectuée, elle peut (encore) aboutir à l'instanciation de la classe d'habillage avec toutes les informations de type si nécessaire (ou la conversion / conversion en une telle).

Ainsi, la différence entre booléen et booléen est exactement dans Compilation et Runtime (un peu loin mais presque comme instanceof vs getClass () ).

Enfin, l'autoboxing est plus lent que les primitives

Notez que Java peut faire de l' autoboxing n'est qu'un "sucre syntaxique". Il n'accélère rien, vous permet simplement d'écrire moins de code. C'est tout. La coulée et l'emballage dans le conteneur d'informations de type sont toujours effectués. Pour des raisons de performances, choisissez l'arithmétique qui ignorera toujours la gestion supplémentaire de la création d'instances de classe avec des informations de type pour implémenter la sécurité de type. Le manque de sécurité de type est le prix à payer pour gagner en performances. Pour le code avec des expressions à valeur booléenne, la sécurité du type (lorsque vous écrivez moins et donc du code implicite ) serait critique, par exemple pour les contrôles de flux if-then-else.


16

Vous pouvez utiliser les constantes booléennes - Boolean.TRUEet Boolean.FALSEau lieu de 0et 1. Vous pouvez créer votre variable de type booleansi la primitive est ce que vous recherchez. De cette façon, vous n'aurez pas à créer de nouveaux Booleanobjets.


3

Fondamentalement, les valeurs booléennes représentent un type de données primitif, où les valeurs booléennes représentent un type de données de référence. cette histoire commence lorsque Java veut devenir purement orienté objet, il est fourni un concept de classe wrapper pour surmonter l'utilisation du type de données primitif.

boolean b1;
Boolean b2;

b1et b2ne sont pas les mêmes.


3

Une observation: (bien que cela puisse être considéré comme un effet secondaire)

booléen étant un primitif peut dire oui ou non.

Boolean est un objet (il peut faire référence à oui ou non ou à «ne sait pas», c'est-à-dire null)


1

Vous pouvez utiliser Boolean / boolean. La simplicité est la voie à suivre. Si vous n'avez pas besoin d'api spécifique (Collections, Streams, etc.) et que vous ne prévoyez pas en avoir besoin - utilisez la version primitive de celui-ci (booléen).

  1. Avec les primitives, vous garantissez que vous ne passerez pas de valeurs nulles.
    Vous ne tomberez pas dans des pièges comme celui-ci. Le code ci-dessous lève NullPointerException (à partir de: booléens, opérateurs conditionnels et autoboxing ):

    public static void main(String[] args) throws Exception { Boolean b = true ? returnsNull() : false; // NPE on this line. System.out.println(b); } public static Boolean returnsNull() { return null; }

  2. Utilisez Boolean lorsque vous avez besoin d'un objet, par exemple:

    • Flux de booléens,
    • Optionnel
    • Collections de booléens
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.