Pourquoi les collections Java ne peuvent-elles pas stocker directement les types de Primitives?
Java collections d'Objets de banque, pas de types primitifs, toutefois, nous pouvons stocker les classes wrapper.
pourquoi cette contrainte?
7 réponses
c'était une décision de conception Java, et que certains considèrent comme une erreur. Les conteneurs veulent des objets et les primitives ne dérivent pas d'un objet.
il s'agit d'un endroit que les concepteurs de .NET ont appris de la JVM et mis en œuvre des types de valeur et génériques de sorte que la boxe est éliminée dans de nombreux cas. Dans CLR, les conteneurs génériques peuvent stocker des types de valeur faisant partie de la structure sous-jacente du conteneur.
Java a choisi d'ajouter un support générique de 100% dans le compilateur sans le soutien de la JVM. La JVM étant ce qu'elle est, elle ne supporte pas un objet "non-object". Java generics vous permet de prétendre qu'il n'y a pas de wrapper, mais vous payez quand même le prix de la boxe. Cela est IMPORTANT pour certaines catégories de programmes.
la Boxe est une technique de compromis, et je pense qu'il est de la mise en œuvre détail de la fuite dans la langue. L'Autoboxing est un bon sucre syntaxique, mais c'est quand même une pénalité de performance. Si quoi que ce soit, j'aimerais que le compilateur me préviens quand il autoboxes. (Pour autant que je sache, il se peut maintenant, j'ai écrit cette réponse en 2010).
Une bonne explication sur DONC sur la boxe: Pourquoi certaines langues ont besoin Boxing et Unboxing?
et la critique de Java generics: pourquoi certains prétendent que L'implémentation de Java de generics est mauvaise?
pour la défense de Java, il est facile de regarder en arrière et de critiquer. La JVM a résisté à l'épreuve de le temps, et est une bonne conception à bien des égards.
facilite la mise en œuvre. Étant donné que les primitives Java ne sont pas considérées comme des objets, vous devez créer une classe collection distincte pour chacune de ces primitives (pas de code modèle à partager).
vous pouvez le faire, bien sûr, juste voir GNU Trove , Apache Commons Primitives ou HPPC .
à moins que vous n'ayez de grandes collections, les frais généraux pour les enveloppes n'est pas assez important pour que les gens s'en soucient (et quand vous avez vraiment de grandes collections primitives, vous pourriez vouloir passer l'effort d'examiner l'utilisation/la construction d'une structure de données spécialisée pour eux).
C'est une combinaison de deux faits:
- les types primitifs Java ne sont pas des types de référence (par exemple, un
int
n'est pas unObject
) - Java ne génériques utilisant type-erasure de types de référence (par exemple, un
List<?>
est vraiment unList<Object>
à l'exécution)
comme les deux sont vraies, les collections Java génériques ne peuvent pas stocker les types primitifs directement. Pour plus de commodité, l'autoboxing est introduit pour permettre aux types primitifs d'être automatiquement encadrés comme types de référence. Ne vous y trompez pas, cependant, les collections sont toujours en train de stocker des références d'objets de toute façon.
cela aurait-il pu être évité? Peut-être.
- si un
int
est unObject
, alors il n'y a pas besoin du tout de types de boîtes. - si les génériques ne sont pas faits en utilisant le type-erasure, alors les primitives auraient pu être utilisées pour les paramètres de type.
il y a le concept de auto-boxing et auto-unboxing. Si vous tentez de stocker un int
dans un List<Integer>
le compilateur Java sera automatiquement convertir en un Integer
.
ce n'est pas vraiment une contrainte, est-il?
réfléchissez si vous voulez créer une collection qui stocke des valeurs primitives. Comment écririez-vous une collection qui peut stocker soit int, ou float ou char? Très probablement, vous finirez avec plusieurs collections, donc vous aurez besoin d'une intlist et un charlist etc.
profitant de la nature orientée objet de Java lorsque vous écrivez une classe collection il peut stocker n'importe quel objet de sorte que vous avez besoin d'un seul classe de collection. Cette idée, le polymorphisme, est très puissante et simplifie grandement la conception des bibliothèques.
je pense que nous pourrions voir des progrès dans cet espace dans le JDK peut - être en Java 10 basé sur ce JEP - http://openjdk.java.net/jeps/218 .
si vous voulez éviter la boxe primitives dans les collections aujourd'hui, il ya plusieurs tiers alternatives. En plus des options de tiers précédemment mentionnées il y a aussi Collections Eclipse , FastUtil et Koloboke .
Une comparaison de la primitive de cartes a également été publié il y a un moment avec le titre: Grande table de hachage présentation: JDK, FastUtil, Goldman Sachs, les PROFESSIONS, Koloboke, Trove . La bibliothèque GS Collections (Goldman Sachs) a été migrée à la Fondation Eclipse et est maintenant Eclipse Collections.
la raison principale est la stratégie de conception java. ++ 1) les collections nécessitent des objets de manipulation et les primitives ne sont pas dérivées d'un objet donc cela peut être l'autre raison. 2) les types de données primitives Java ne sont pas des types de référence pour ex. l'int n'est pas un objet.
À Surmonter: -
nous avons le concept d'auto-boxe et auto-unboxing. donc, si vous essayez de stocker des types de données primitifs compilateur convertit en objet de cette classe de données primitives.