En Java, les chaînes sont stockées dans la mémoire en tant qu'objets de la classe String.
Lorsque la mémoire est allouée à un programme Java, la JVM (machine virtuelle Java) divise la mémoire allouée en deux parties. Une partie est Stack et l’autre partie est Heap. Dans la mémoire Heap, Java alloue de la mémoire, en particulier pour les littéraux, cette mémoire est appelée pool constant de chaînes (SCP). SCP est la zone prédéfinie à l'intérieur du tas. Le pool de chaînes permet d'économiser beaucoup d'espace pour Java Runtime. La classe String utilise SCP pour stocker des littéraux de chaîne uniques.
Dans la mémoire Stack, les variables ou les références de variables ou les références aux objets sont stockées.
Dans la mémoire Heap, tous les objets alloués dynamiquement sont stockés. Pour allouer de la mémoire à un objet, nous utilisons un nouveau mot-clé.
Il existe deux façons de créer des objets chaîne.
String str1 = « MaChaîne » ;
Chaque fois que nous créons un littéral de chaîne, JVM vérifie d'abord si le littéral de chaîne existe déjà dans le pool de constantes de chaîne. S'il n'est pas disponible, il créera une nouvelle chaîne littérale dans SCP.
Dans l'image ci-dessus, str1 pointe vers « MyString » dans SCP. Voici comment les chaînes littérales nouvellement créées sont gérées.
String str2 = new String("MaChaîne"); //Instanciation de la classe string à l'aide d'un nouveau mot-clé
Lorsqu'un objet chaîne est créé à l'aide d'un nouveau mot-clé, il créera deux objets. Un dans SCP, un autre dans Heap et la variable de référence est stockée dans la pile.
Nous avons déjà créé le littéral « MyString » en utilisant
String str1 = « MaChaîne » ;
Comme nous ne pouvons pas avoir de doublons dans SCP, JVM ne créera donc pas un objet supplémentaire dans SCP mais renverra la référence existante à la variable str3 dans la pile et créera un objet dans Heap. Str3 pointera vers l'objet « MyString » dans le Heap mais pas dans SCP.
Voici les différents cas d'allocation de mémoire pour les objets chaîne.
Cas 1 : Comment les objets chaîne définis ci-dessus sont stockés en mémoire.
chaînes de classe publiquesStorageConcept
{
public static void main(String[] args)
{
String str1 = « MaChaîne » ;
String str2 = new String("MyString");
System.out.println(str1 == str2); //Sortie : Faux
System.out.println(str1.equals(str2)); //Sortie : Vrai
}
}
Lorsque nous comparons str1 et str2 en utilisant l'opérateur « == », cela renvoie false. Comme nous le savons, l'opérateur « == » compare leurs adresses physiques. Ici, dans notre exemple, str1 pointe vers l'objet dans SCP et str2 pointe vers l'objet dans le tas. Donc ça renvoie faux.
Mais dans le cas de str1.equals(str2), comme nous le savons, la fonction « égal » vérifie que les caractères individuels str1 et str3 ont la même valeur stockée et renvoie vrai.
Cas 2 : Une autre chaîne littérale
String str3 = « MaChaîne » ;
Str1 et str3 pointeront vers le même littéral de chaîne dans SCP.
chaînes de classe publiquesStorageConcept
{
public static void main(String[] args)
{
String str1 = « MaChaîne » ;
String str3 = « MaChaîne » ;
System.out.println(str1 == str2); //Sortie : Vrai
System.out.println(str1.equals(str2)); //Sortie : Vrai
}
}
s1 == s3 renvoie vrai, car l'opérateur « == » compare leurs adresses physiques mais pas le contenu.
s1.equals(s3) renvoie vrai et la fonction « equals » vérifie les caractères individuels dans les deux variables de référence.
Cas 3 : Un autre objet chaîne est créé à l'aide d'un nouveau mot-clé
String str4 = new String("NewString");
Dans ce cas, JVM vérifiera cette chaîne dans SCP, elle ne trouvera pas l'objet chaîne avec la valeur « NewString », elle créera donc deux objets, un dans SCP et un autre dans Heap, la variable de référence str4 sera stockée dans la pile. Str4 aura la référence à l'objet dans le Heap.
Cas 4 : Un autre littéral de chaîne est créé.
String str5 = « NouvelleChaîne »;
Dans ce cas, JVM vérifiera dans SCP si ce littéral est déjà disponible ou non, ici « NewString » est déjà présent dans SCP donc JVM ne créera pas de doublon dans SCP mais renvoie la référence à la variable str5.
Cas 5 : Affectation d'une chaîne à une autre chaîne
String str4 = new String("NewString");
Chaîne str6 = str4; //Attribution
Ici str6 et str4 pointeront vers le même objet dans Heap et n'effaceront pas la valeur dans str4.
chaînes de classe publiquesStorageConcept
{
public static void main(String[] args)
{
String str4 = new String("NewString");
Chaîne str6 = str4;
System.out.println(str4 == str6); //Sortie : vrai
}
}
JVM donnera la référence du « NewString » dans le tas à la variable str6. C'est la raison pour laquelle str4 == str6 renvoie true.
En conclusion, créer des objets chaîne en utilisant une chaîne littérale et par un opérateur « nouveau » a ses avantages et ses inconvénients.
En utilisant des chaînes littérales, nous pouvons rendre la mémoire plus efficace en ne créant pas de doublons. JVM crée un objet unique et la chaîne reste pour toujours dans le SCP. L'inconvénient est que le pool de cordes a une taille fixe et qu'il sera plein à un moment donné.
Mais en utilisant un nouveau mot-clé, il crée deux objets, un dans SCP et l'autre dans Heap. Dans un tas, si nous n'avons pas besoin de l'objet, il sera effacé par un ramasse-miettes pour libérer de l'espace. Mais l’inconvénient est qu’avec un « nouvel » opérateur, JVM devra toujours créer un nouvel objet et c’est une surcharge pour JVM.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!