web-dev-qa-db-fra.com

Boolean vs boolean en Java

Il y a des discussions sur Integer vs int en Java. La valeur par défaut du premier est null tandis que dans le dernier c'est 0. Que diriez-vous de Boolean vs boolean

Une variable dans mon application peut avoir des valeurs de 0/1. J'aimerais utiliser boolean/Boolean et préférer ne pas utiliser int. Puis-je utiliser Boolean/boolean à la place?

149
Neel

Oui vous pouvez utiliser Boolean/boolean à la place.

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

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

  • La seconde est peu coûteuse compte tenu des dépenses en mémoire La seconde vous fera économiser beaucoup plus de mémoire, alors foncez

Maintenant, choisissez votre chemin.

217
Jigar Joshi

Booleanwraps le type primitif booléen. À partir de JDK 5, Oracle (ou Sun avant que Oracle les ait achetés) a introduit autoboxing/unboxing , qui permet essentiellement

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.

47
Buhake Sindi

Je suis un peu en train d’élargir les réponses fournies (car jusqu’à présent, ils se concentrent sur leur propre terminologie/artificielle mettant l’accent sur la programmation d’un langage particulier au lieu de s’occuper de la situation dans son ensemble, créant les langages de programmation, en général , c’est-à-dire lorsque des considérations telles que la sécurité du type ou 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:0 illustre le fait que bar (boolean) ne peut pas être converti implicitement (converti) en un fichier int. Je soulève cette question non pas pour illustrer les détails de l’implémentation derrière la machine virtuelle Java, mais pour souligner qu’en termes de considérations de bas niveau (comme la taille de la mémoire), il est préférable de préférer les valeurs à la sécurité du type. Surtout si la sécurité de ce type n’est pas vraiment/pleinement utilisée comme dans les types booléens où les contrôles sont effectués sous forme de vérification. 

si la valeur\in {0,1} est convertie en type booléen, sinon émet une exception.

Tout cela pour dire que {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. On dirait un excès, non? La sécurité des types est vraiment importante dans les types définis par l'utilisateur, pas dans la transposition implicite de primitives (bien que les derniers soient inclus dans le premier).

Octets ne sont pas des types ou des bits

Notez qu'en mémoire votre variable de la plage {0,1} occupera toujours au moins un octet ou un mot (xbits en fonction de la taille du registre) sauf si elle est spécialement soignée (par exemple, bien rangée dans la mémoire - 8 "booléen" bits en 1 octet - en avant et en arrière).

En préférant la sécurité du type (par exemple, en plaçant une valeur dans une boîte d'un type particulier) plutôt qu'une compression de valeur supplémentaire (par exemple, en utilisant des décalages de bits ou des calculs), on choisit effectivement d'écrire moins de code que de gagner plus de mémoire. (Par contre, on peut toujours définir un type d’utilisateur personnalisé qui facilitera toutes les conversions ne valant que du booléen).

mot-clé vs type

Enfin, votre question concerne la comparaison entre mot clé et type. Je pense qu'il est important d'expliquer pourquoi ou comment vous obtiendrez des performances exactes en utilisant/en préférant les mots-clés ("marqué" par primitive ) par rapport aux types (classes composites normales définissables par l'utilisateur utilisant un autre mot-clé class) ou en d'autres termes

boolean foo = true;

vs.

Boolean foo = true;

La première "chose" (type) ne peut pas être étendue (sous-classée) et non sans raison. La terminologie Java des classes primitive et wrapping peut être simplement traduite en valeur inline (une LITERAL ou une constante qui est directement substituée par le compilateur chaque fois qu'il est possible d'inférer la substitution ou si elle ne l'est pas. - toujours replier en emballant la valeur). 

L'optimisation est obtenue grâce à des éléments triviaux:

"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’enveloppement avec toutes les informations de type si nécessaire (ou à une conversion/diffusion en telle).

Ainsi, la différence entre boolean et Boolean 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 le fait que Java peut faire autoboxing est juste un "sucre syntaxique". Cela n'accélère rien, il vous permet simplement d'écrire moins de code. C'est tout. Le moulage et l'emballage dans le conteneur d'informations de type sont toujours effectués. Pour des raisons de performances, choisissez arithmétique, qui omettra toujours des tâches supplémentaires lors de la création d’instances de classe avec des informations de type afin d’implémenter la sécurité de type. Le manque de type de sécurité est le prix à payer pour gagner en performance. Pour le code avec des expressions à valeur booléenne, le type sécurité (lorsque vous écrivez moins et donc le code implicite) serait critique, par exemple. pour les contrôles de flux if-then-else.

33
Yauhen Yakimovich

Vous pouvez utiliser les constantes booléennes - Boolean.TRUE et Boolean.FALSE au lieu de 0 et 1. Vous pouvez créer votre variable à partir du type boolean si primitive correspond à ce que vous recherchez. De cette façon, vous n'aurez pas à créer de nouveaux objets Boolean

16
CoolBeans

Fondamentalement, boolean représente un type de données primitif alors que Boolean représente un type de données de référence. cette histoire est lancée quand Java veut devenir purement orienté objet, c'est un concept de classe wrapper qui lui permet de maîtriser le type de données primitif.

boolean b1;
Boolean b2;

b1 et b2 ne sont pas identiques.

3
Sachin Jadhav

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

boolean être 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
Sudip Bhandari

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-en une version primitive (booléenne).

  1. Avec les primitives, vous garantissez que vous ne passerez pas les valeurs NULL. 
    Vous ne tomberez pas dans des pièges comme celui-ci. Le code ci-dessous lève NullPointerException (from: Booleans, 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
0
Witold Kaczurba