Je vois que Java a Boolean (classe) vs boolean (primitive). De même, il y a un Integer (classe) vs int (primitive). Quelle est la meilleure pratique pour utiliser la version primitive par rapport à la classe? Devrais-je toujours utiliser la version de classe à moins d’avoir une raison spécifique (performance?) De ne pas le faire? Quelle est la manière la plus courante et acceptée d’utiliser chacun?
54
Réponses:
Dans l'article 5 de Java efficace, Joshua Bloch dit
Une bonne utilisation des classes consiste à les utiliser comme types génériques (y compris les classes Collection, telles que des listes et des mappes) ou à les transformer en un autre type sans transtypage implicite (par exemple,
Integer
classe a des méthodesdoubleValue()
oubyteValue()
.Edit: La raison de Joshua Bloch est:
la source
La pratique habituelle consiste à utiliser les primitives, à moins que vous n'utilisiez des génériques (assurez-vous que vous êtes au courant de l' autoboxing et de la déballage !).
Il y a plusieurs bonnes raisons de suivre la convention:
1. Vous évitez les erreurs simples:
Il existe des cas subtils et non intuitifs qui attrapent souvent les débutants. Même des codeurs expérimentés font des erreurs et font parfois ces erreurs (j'espère que cela sera suivi de jurons quand ils débogueront le code et trouveront l'erreur!).
L’erreur la plus courante est d’utiliser
a == b
au lieu dea.equals(b)
. Les gens sont habitués à utiliser desa == b
primitives, alors vous pouvez le faire facilement lorsque vous utilisez les wrappers d’objets.2. Lisibilité:
Considérez les deux exemples suivants. La plupart des gens diraient que la seconde est plus lisible.
3. Performance:
Le fait est qu'il est plus lent d'utiliser les wrappers d'objet pour les primitives que de simplement utiliser les primitives. Vous ajoutez le coût de l'instanciation d'objet, des appels de méthode, etc. aux éléments que vous utilisez partout .
Knuth "... disons environ 97% du temps: l'optimisation prématurée est la racine de tout le mal" citation ne s'applique pas vraiment ici. Il parlait Optimisations qui rend plus compliqué le code (ou système) - si vous êtes d' accord avec le point # 2, ceci est une optimisation qui rend le code moins compliqué!
4. C'est la convention:
Si vous faites des choix stylistiques différents pour 99% des autres programmeurs Java, il y a 2 inconvénients:
Normalement, je listerais quelques contre-points, mais honnêtement, je ne vois aucune bonne raison de ne pas aller à la convention ici!
la source
==
. Les objets doivent être comparés avecequals()
.equals()
... vous leur donnez une solution de contournement afin que la comparaison d'objets avec==
les résultats attendus.equals()
au deuxième extrait de code et changé mon vote.D'habitude je vais avec les primitives. Cependant, une particularité d'utiliser des classes comme
Integer
etBoolean
est la possibilité d'assignernull
à ces variables. Bien sûr, cela signifie que vous devez faire desnull
vérifications tout le temps, mais il vaut mieux obtenir une exception NullPointerException que d'avoir des erreurs de logique dues à l'utilisation d'une variableint
ou d'uneboolean
variable qui n'a pas été initialisée correctement.Bien sûr, depuis Java 8, vous pouvez (et devriez probablement) aller plus loin et
Integer
vous pouvez, au lieu de, par exemple, utiliserOptional<Integer>
des variables qui peuvent ou non avoir une valeur.De plus, cela introduit la possibilité d'utiliser
null
pour attribuer à ces variables une valeur " inconnue " ou " générique ". Cela peut être pratique dans certaines situations, par exemple dans la logique ternaire . Vous pouvez également vérifier si un objet donné correspond à un modèle. dans ce cas, vous pouvez utilisernull
les variables du modèle pouvant avoir une valeur quelconque dans l'objet.la source
null
une valeur par défaut. Au contraire: vous feriez mieux de ne pas "initialiser" la variable du tout. La définition de toute valeur par défaut, mêmenull
, ferme le compilateur ... mais l'empêche également de détecter l'absence d' affectation utile le long de tous les chemins de code. Ainsi, une erreur que le compilateur aurait pu intercepter se glisse dans l'exécution.0.0
, ou-1
, ouInteger.MAX_VALUE
, ouFalse
, mais au final, vous ne savez pas s'il s'agit de la valeur par défaut ou d'une valeur réelle affectée à cette variable. Dans les cas où cela est important, avoir unenull
valeur peut être plus clair.null
présentent toute une série de problèmes, y compris une paranoïa nulle.) Dans une fonction, une variable qui peut en réalité ne pas être initialisée au moment de l’utilisation indique généralement des cas non couverts. (L'analyse d'attribution définie est simpliste, donc des faux positifs sont possibles. Mais vous pouvez souvent les résoudre en simplifiant la logique, alors.)En termes simples:
Vous utilisez les wrappers lorsque vous devez ajouter des éléments aux collections.
Les collections ne peuvent pas contenir de primitives.
la source
Comme le mentionne m3th0dman, les fonctionnalités Java sont automatiques. Pensez au niveau le plus bas possible et vous verrez que la valeur primitive de la sélection automatique (entrée ou sortie) implique des cycles d'horloge utilisés dans certaines tâches inutiles si vous utilisez des types de données natifs autour de votre application.
En règle générale, vous devriez essayer d'utiliser des types de données natifs autant que possible.
la source