Les collections Java stockent uniquement des objets, pas des types primitifs; cependant, nous pouvons stocker les classes wrapper.
Pourquoi cette contrainte?
java
collections
types
primitive-types
JavaUser
la source
la source
class
, plutôt par la JVM. L'instructionint i = 1
définit un pointeur vers l'instance singleton de l'objet qui définitint
dans la JVM, définie sur la valeur1
définie quelque part dans la JVM. Oui, des pointeurs en Java - cela vous est simplement retiré par l'implémentation du langage. Les primitives ne peuvent pas être utilisées comme génériques car les prédicats de langage tous les types génériques doivent être du supertypeObject
- d'où la raison de laA<?>
compilationA<Object>
au moment de l'exécution.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'Object.
C'est un endroit que les concepteurs .NET ont appris de la JVM et ont implémenté des types de valeur et des génériques tels que la boxe est éliminée dans de nombreux cas. Dans CLR, les conteneurs génériques peuvent stocker des types valeur dans le cadre de la structure de conteneur sous-jacente.
Java a choisi d'ajouter une prise en charge générique à 100% dans le compilateur sans prise en charge de la JVM. La JVM étant ce qu'elle est, ne supporte pas un objet "non-objet". Les génériques Java vous permettent de prétendre qu'il n'y a pas de wrapper, mais vous payez toujours le prix des performances de la boxe. Ceci est IMPORTANT pour certaines classes de programmes.
La boxe est un compromis technique, et je pense que ce sont des détails d'implémentation qui fuient dans la langue. L'autoboxing est un bon sucre syntaxique, mais c'est toujours une pénalité de performance. Si quoi que ce soit, j'aimerais que le compilateur me prévienne lorsqu'il effectue des boîtes automatiques. (Pour autant que je sache, il se peut maintenant, j'ai écrit cette réponse en 2010).
Une bonne explication sur SO sur la boxe: Pourquoi certaines langues ont-elles besoin de boxe et de déballage?
Et la critique des génériques Java: pourquoi certains prétendent que l'implémentation Java des génériques est mauvaise?
Dans la défense de Java, il est facile de regarder en arrière et de critiquer. La JVM a résisté à l'épreuve du temps et constitue une bonne conception à bien des égards.
la source
Object.ReferenceEquals
références de typeObject
qui identifient des entiers encadrés, mais cela ne devrait pas être légal pour passer une valeur entière]. Le déballage automatique de Java est à mon humble avis tout simplement méchant.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 de collection distincte pour chacune de ces primitives (pas de code de modèle à partager).
Vous pouvez le faire, bien sûr, il suffit de voir GNU Trove , Apache Commons Primitives ou HPPC .
À moins que vous n'ayez de très grandes collections, la surcharge des wrappers n'a pas suffisamment d'importance pour que les gens s'en soucient (et lorsque vous avez de très grandes collections primitives, vous voudrez peut-être consacrer l'effort à utiliser / construire une structure de données spécialisée pour eux. ).
la source
C'est une combinaison de deux faits:
int
n'est pas unObject
)List<?>
est vraiment unList<Object>
au moment de l'exécution)Étant donné que ces deux conditions sont vraies, les collections Java génériques ne peuvent pas stocker directement les types primitifs. Pour plus de commodité, la mise en boîte automatique est introduite pour permettre aux types primitifs d'être automatiquement encadrés en tant que types de référence. Ne vous y trompez pas, cependant, les collections stockent toujours des références d'objets.
Cela aurait-il pu être évité? Peut-être.
int
est unObject
, il n'y a aucun besoin de type de boîte.la source
Il y a le concept d' auto-boxing et d'auto-unboxing. Si vous essayez de stocker un
int
dans un,List<Integer>
le compilateur Java le convertira automatiquement en fichierInteger
.la source
Ce n'est pas vraiment une contrainte, n'est-ce pas?
Considérez si vous souhaitez créer une collection contenant des valeurs primitives. Comment écririez-vous une collection qui peut stocker soit int, soit float ou char? Très probablement, vous vous retrouverez avec plusieurs collections, vous aurez donc besoin d'une intlist et d'une charlist, etc.
Tirant parti de la nature orientée objet de Java lorsque vous écrivez une classe de collection, il peut stocker n'importe quel objet, vous n'avez donc besoin que d'une seule classe de collection. Cette idée, le polymorphisme, est très puissante et simplifie grandement la conception des bibliothèques.
la source
Je pense que nous pourrions voir des progrès dans cet espace dans le JDK éventuellement dans Java 10 basé sur ce JEP - http://openjdk.java.net/jeps/218 .
Si vous souhaitez éviter de boxer les primitives dans les collections d'aujourd'hui, il existe plusieurs alternatives tierces. En plus des options tierces mentionnées précédemment, il existe également des collections Eclipse , FastUtil et Koloboke .
Une comparaison de cartes primitives a également été publiée il y a quelque temps avec le titre: Large HashMap overview: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . La bibliothèque GS Collections (Goldman Sachs) a été migrée vers Eclipse Foundation et s'appelle désormais Eclipse Collections.
la source
La principale raison est la stratégie de conception java. ++ 1) les collections nécessitent des objets pour la manipulation et les primitives ne sont pas dérivées de l'objet, ce peut donc être l'autre raison. 2) Les types de données primitifs Java ne sont pas des types de référence par exemple. int n'est pas un objet.
Surpasser:-
nous avons le concept d'auto-boxing et d'auto-unboxing. donc si vous essayez de stocker des types de données primitifs, le compilateur le convertira automatiquement en objet de cette classe de données primitive.
la source