Votre confusion est le résultat d'une mauvaise compréhension de la relation entre la pile, le tas et les variables. Voici la façon correcte d'y penser.
- Une variable est un emplacement de stockage qui a un type.
- La durée de vie d'une variable peut être courte ou longue. Par "courte", nous entendons "jusqu'à ce que la fonction actuelle renvoie ou jette" et par "longue", nous entendons "éventuellement plus longtemps que cela".
- Si le type d'une variable est un type de référence, alors le contenu de la variable est une référence à un emplacement de stockage à longue durée de vie. Si le type d'une variable est un type de valeur, le contenu de la variable est une valeur.
En tant que détail d'implémentation, un emplacement de stockage qui est garanti pour être de courte durée peut être alloué sur la pile. Un emplacement de stockage qui pourrait avoir une longue durée de vie est alloué sur le tas. Notez que cela ne dit rien sur "les types de valeurs sont toujours alloués sur la pile". Les types de valeurs sont pas toujours alloué sur la pile :
int[] x = new int[10];
x[1] = 123;
x[1]
est un emplacement de stockage. Il a une longue durée de vie ; il pourrait vivre plus longtemps que cette méthode. Il doit donc se trouver sur le tas. Le fait qu'il contienne un int n'est pas pertinent.
Vous avez bien dit pourquoi une boîte d'int est chère :
Le prix de la mise en boîte est la nécessité de créer un objet sur le tas, de copier l'entier alloué par la pile dans le nouvel objet et vice-versa pour la mise hors boîte.
Là où vous vous trompez, c'est en disant "le nombre entier alloué par la pile". L'endroit où l'entier a été alloué n'a pas d'importance. Ce qui compte, c'est que son stockage contenait le nombre entier au lieu de contenir une référence à un emplacement de tas . Le prix correspond à la nécessité de créer l'objet et de faire la copie ; c'est le seul coût pertinent.
Alors pourquoi une variable générique n'est-elle pas coûteuse ? Si vous avez une variable de type T, et que T est construit pour être int, alors vous avez une variable de type int, point. Une variable de type int est un emplacement de stockage, et elle contient un int. Que cet emplacement de stockage soit sur la pile ou le tas n'a aucune importance. . Ce qui est important, c'est que le lieu de stockage contient un int au lieu de contenir une référence à quelque chose sur le tas . Puisque l'emplacement de stockage contient un int, vous n'avez pas à assumer les coûts du boxing et du unboxing : allocation d'un nouveau stockage sur le tas et copie de l'int dans le nouveau stockage.
Est-ce que c'est maintenant clair ?