59 votes

Combien d'objets sont créés à l'aide de la classe wrapper Integer?

 Integer i = 3; 
i = i + 1; 
Integer j = i; 
j = i + j; 
 

Combien d'objets sont créés à la suite des instructions de l'exemple de code ci-dessus et pourquoi? Existe-t-il un environnement de développement intégré dans lequel nous pouvons voir le nombre d’objets créés (peut-être en mode débogage)?

101voto

Bathsheba Points 23209

La réponse, étonnamment, est zéro.

Tous les Integer s de -128 à +127 sont pré-calculés par la JVM.

Votre code crée des références à ces objets existants .

60voto

Stephen C Points 255558

La stricte réponse correcte est que le nombre d' Integer objets créés est de durée indéterminée. Il pourrait être compris entre 0 et 3, ou 2561 ou même plus2, selon

  • la plate-forme Java3,
  • si c'est la première fois que ce code est exécuté, et
  • (peut-être) si un autre code qui s'appuie sur la boxe de l' int valeurs s'exécute avant de4.

L' Integer valeurs de -128 à 127 ne sont pas strictement nécessaires pour être précalculées. En fait, JLS 5.1.7 qui précisait la Boxe conversion dit ceci:

Si la valeur de p étant le coffret est un entier littéral de type int compris entre -128 et 127 inclus (§3.10.1) ... alors soient a et b les résultats de deux de boxe conversions de p. C'est toujours le cas a == b.

Deux choses à noter:

  • Le JLS seulement exige ce pour >>les littéraux<<.
  • JL n'a pas de mandat désireux de mise en cache des valeurs. Paresseux de la mise en cache est également conforme à la JLS comportementaux des exigences.

Même la javadoc pour Integer.valueof(int) ne permet pas de préciser que les résultats sont mis en cache avec impatience.

Si l'on examine le code source Java SE pour java.lang.Integer de Java 6 à 8, il est clair que l'Java SE de la mise en œuvre de la stratégie est de précalculer les valeurs. Cependant, pour diverses raisons (voir ci-dessus) qui n'est pas encore suffisant pour nous permettre de donner une réponse définitive à la "combien d'objets" à la question.


1 - C'est peut-être de 256 si l'exécution du code ci-dessus déclenche initialisation de classe pour Integer dans une version de Java où le cache est très initialisé lors de l'initialisation de classe.

2 - C'est peut-être même plus, si le cache est plus grande que la JVM spec exige. La taille du cache peut être augmentée grâce à une option JVM dans certaines versions de Java.

3 - En plus de la plate-forme de l'approche générale pour la mise en œuvre de la boxe, un compilateur pu observer que certains ou la totalité du calcul pourrait être fait au moment de la compilation ou optimisé, il disparaître entièrement.

4 - un Tel code pourrait déclencher des paresseux ou désireux de l'initialisation de l'entier de cache.

17voto

Denis Lukenich Points 1590

Tout d'abord: La réponse que vous cherchez est - 0, comme d'autres, déjà mentionné.

Mais nous allons aller un peu plus profond. Comme Stephen menthioned ça dépend du temps que vous l'exécuter. Parce que le cache est en fait paresseux initialisé.

Si vous regardez la documentation de java.lang.Entier.IntegerCache:

Le cache est initialisé à la première utilisation.

Cela signifie que si c'est la première fois que vous appelez tout Entier de le créer:

  • 256 Entier des Objets (ou plus: voir ci-dessous)
  • 1 Objet pour le Tableau pour stocker les nombres Entiers
  • Nous allons ignorer les Objets nécessaires pour Stocker la Classe (et les Méthodes / Champs). Ils sont stockés dans le metaspace.

À partir de la deuxième fois sur vous les appelez, vous créez 0 Objets.


Les choses deviennent plus drôle une fois que vous faites le nombre un peu plus élevé. E. g. par l'exemple suivant:

Integer i = 1500; 

Les options valides sont: 0, 1 ou n'importe quel nombre entre 1629 à 2147483776 (cette fois seulement compter le créé Entier-valeurs. Pourquoi? La réponse est donnée dans la phrase suivante de l'Entier de la mémoire Cache de définition:

La taille du cache peut être contrôlée par la -XX:AutoBoxCacheMax= option.

Donc en fait vous pouvez faire varier la taille de la mémoire cache qui est mis en œuvre.

Ce qui signifie que vous pouvez atteindre pour la ligne ci-dessus:

  • 1: nouvel Objet si votre cache est inférieure à 1500
  • 0: de nouveaux Objets si votre cache a été initialisé avant et contient 1500
  • 1629: nouveau (Entier) - Objets si votre cache est exactement 1500 et n'a pas été initialisé encore. Puis Entier-valeurs de -128 à 1500 va être créé.
  • Comme dans la phrase ci-dessus vous atteindre n'importe quel montant de l'entier des Objets ici: Integer.MAX_VALUE + 129, qui est mentionné: 2147483776.

Gardez à l'esprit: Ce n'est garantie que sur Oracle / Open JDK (j'ai vérifié la Version 7 et 8)

Comme vous pouvez le voir complètement réponse correcte n'est pas si facile à obtenir. Mais juste dire 0 va rendre les gens heureux.


PS: à l'aide de la menthoned paramètre peut faire la déclaration suivante vrai: Integer.valueOf(1500) == 1500

5voto

Boann Points 11904

Le compilateur unboxes la Integer objets d' ints pour faire de l'arithmétique avec eux en appelant intValue() sur, et il Integer.valueOf de zone de l' int résultats lorsqu'ils sont affectés à l' Integer variables, de sorte que votre exemple est équivalent à:

Integer i = Integer.valueOf(3);
i = Integer.valueOf(i.intValue() + 1);
Integer j = i;
j = Integer.valueOf(i.intValue() + j.intValue());

La cession j = i; est tout à fait normal de référence d'objet de cession qui ne crée pas de nouveaux objets. Il n'est pas de la boxe ou l'unboxing, et n'a pas besoin de tant Integer des objets sont immuables.

L' valueOf méthode est autorisé à mettre en cache des objets et retourner la même instance à chaque fois pour un numéro particulier. Il est nécessaire de cache ints -128 à +127. Pour votre numéro de départ de l' i = 3, tous les nombres sont petits et la garantie d'être mis en cache, de sorte que le nombre d'objets qui doivent être créés est de 0. Strictement parlant, valueOf est autorisé à mettre en cache les instances paresseusement plutôt que de les avoir tous les pré-générés, afin que l'exemple peut encore créer des objets la première fois, mais si le code est exécuté à plusieurs reprises au cours d'un programme, le nombre d'objets créés à chaque fois en moyenne approches 0.

Si vous commencez avec un plus grand nombre dont les instances ne sera pas mis en cache (par exemple, i = 300)? Ensuite, chaque valueOf appel doit créer un nouveau Integer de l'objet, et le nombre total d'objets créés à chaque fois est 3.

(Ou, peut-être que c'est toujours égale à zéro, ou peut-être des millions. Rappelez-vous que les compilateurs et les machines virtuelles sont autorisés à réécrire le code pour l'exécution ou la mise en œuvre des raisons, tant que son comportement n'est pas modifiée. Donc, on pourrait supprimer le code ci-dessus entièrement si vous n'avez pas utiliser le résultat. Ou si vous essayez d'imprimer j, il pourrait réaliser qu' j finiront toujours avec la même valeur de la constante après l'extrait ci-dessus, et de faire tous les calculs arithmétiques au moment de la compilation, et d'imprimer une valeur constante. Le montant réel du travail effectué en coulisses pour exécuter votre code est toujours un détail d'implémentation.)

2voto

Cootri Points 2465

Vous pouvez déboguer la méthode Integer.valueOf (int i) pour la découvrir vous-même. Cette méthode est appelée par le processus de sélection automatique par le compilateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X