Le tas et la pile sont des concepts très importants dans la structure de données Java. Cet article analyse plus en détail la différence entre les deux. Pour votre référence. Les détails sont les suivants :
Le tas de Java est une zone de données d'exécution à partir de laquelle les objets de classe allouent de l'espace. Ces objets sont créés via des instructions telles que new, newaray, anewarray et multianewarray, et ils ne nécessitent pas que le code du programme soit explicitement libéré. Le tas est collecté par garbage collection. Responsable, l'avantage du tas est qu'il peut allouer dynamiquement la taille de la mémoire, et la durée de vie n'a pas besoin d'être indiquée au compilateur à l'avance, car il alloue dynamiquement la mémoire au moment de l'exécution, et le garbage collector de Java collectera automatiquement celles qui ne sont plus utilisées. données. Mais l'inconvénient est qu'en raison de la nécessité d'allouer dynamiquement de la mémoire au moment de l'exécution, la vitesse d'accès est lente.
L'avantage de la pile est que la vitesse d'accès est plus rapide que celle du tas, juste derrière le registre, et que les données de la pile peuvent être partagées. Mais l’inconvénient est que la taille et la durée de vie des données stockées dans la pile doivent être déterminées et qu’il y a un manque de flexibilité. La pile stocke principalement certains types de variables de base (int, short, long, byte, float, double, boolean, char) et des descripteurs d'objets.
Une particularité très importante de la pile est que les données stockées dans la pile peuvent être partagées. Supposons que nous définissions également :
entier a = 3 ;
int b = 3;
Le compilateur traite d'abord int a = 3 ; il crée d'abord une référence à la variable a sur la pile, puis vérifie s'il y a une valeur de 3 sur la pile. Si elle n'est pas trouvée, il stocke 3, puis pointe a vers. 3. Ensuite, traitez int b = 3 ; après avoir créé la variable de référence de b, car il y a déjà une valeur de 3 sur la pile, b sera pointé directement vers 3. De cette façon, il existe une situation où a et b pointent tous deux vers 3 en même temps.
À ce stade, si a = 4 est à nouveau défini ; alors le compilateur recherchera à nouveau s'il y a une valeur 4 dans la pile. Sinon, il stockera 4 et fera un point sur 4 s'il existe déjà. pointera directement a vers cette adresse. Par conséquent, les changements dans la valeur de a n’affecteront pas la valeur de b.
Il est à noter que ce type de partage de données est différent du partage de références de deux objets pointant vers un objet en même temps, car dans ce cas la modification de a n'affectera pas b, elle est complétée par le compilateur, qui est bénéfique pour économiser de l'espace. Si une variable de référence d'objet modifie l'état interne de l'objet, cela affectera une autre variable de référence d'objet.
La chaîne est un type de données spécial. Peut être utilisé :
Chaîne str = new String("abc");String str = "abc";
Il existe deux façons de le créer. La première consiste à utiliser new() pour créer un nouvel objet, qui sera stocké dans le tas. Un nouvel objet est créé à chaque appel.
La deuxième méthode consiste à créer d'abord une variable de référence d'objet str de la classe String sur la pile, puis à vérifier si "abc" est stocké dans la pile. Sinon, stockez "abc" sur la pile et faites pointer str vers "abc". ". , s'il y a déjà "abc", pointez directement str vers "abc".
Lorsque vous comparez si les valeurs d'une classe sont égales, utilisez la méthode equals() ; lorsque vous testez si les références de deux classes wrapper pointent vers le même objet, utilisez ==.
Chaîne str1 = "abc" ; Chaîne str2 = "abc" ; System.out.println(str1==str2);
On peut voir que str1 et str2 pointent vers le même objet.
String str1 =nouvelle chaîne ("abc"); String str2 =nouvelle chaîne ("abc");
Utiliser new consiste à générer différents objets. Générez-en un à la fois.
Par conséquent, si vous utilisez la première méthode pour créer plusieurs chaînes "abc", il n'y a en fait qu'un seul objet dans la mémoire. Cette façon d'écrire permet d'économiser de l'espace mémoire. En même temps, elle peut améliorer la vitesse d'exécution. programme dans une certaine mesure, car la JVM déterminera automatiquement s'il est nécessaire de créer un nouvel objet en fonction de la situation réelle des données dans la pile. Pour le code de String str = new String("abc");, de nouveaux objets sont toujours créés dans le tas, que leurs valeurs de chaîne soient égales ou qu'il soit nécessaire de créer de nouveaux objets, augmentant ainsi la charge sur le programme.
Par contre, attention : Lorsque nous définissons une classe en utilisant un format tel que String str = "abc";, nous supposons toujours que l'objet str de la classe String est créé. Attention aux pièges ! L'objet n'a peut-être pas été créé ! Au lieu de cela, il peut simplement pointer vers un objet créé précédemment. Ce n'est que grâce à la méthode new() que nous pouvons garantir qu'un nouvel objet est créé à chaque fois.
En raison de la nature immuable de la classe String, lorsqu'une variable String doit fréquemment modifier sa valeur, vous devez envisager d'utiliser la classe StringBuffer pour améliorer l'efficacité du programme.
J'espère que ce que décrit cet article sera utile à l'apprentissage de la programmation Java par chacun.