JavaRush /Blog Java /Random-FR /Traduction : Création d'objets String en Java - en utilis...
FellowSparrow
Niveau 12
Lvov

Traduction : Création d'objets String en Java - en utilisant " " ou un constructeur ?

Publié dans le groupe Random-FR
Original : Créer une chaîne Java à l'aide de « » ou d'un constructeur ? Par X Wang Traduction : Création d'objets chaîne en Java - UtilisationEn Java, une chaîne peut être créée en utilisant deux méthodes :
String x = "abc";
String y = new String("abc");
Quelle est la différence entre utiliser des guillemets doubles et utiliser un constructeur ?

1. Guillemets doubles vs. Constructeur

On peut répondre à cette question en examinant deux exemples simples. Exemple 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==bvrai car ils font atous deux bréférence au même objet - une chaîne déclarée comme littéral (chaîne littérale ci-dessous) dans la zone méthode (nous renvoyons le lecteur à la source de notre ressource : Top 8 des diagrammes pour comprendre Java , diagramme 8). Lorsque la même chaîne littérale est créée plus d'une fois, une seule copie de la chaîne est stockée en mémoire, une seule instance de celle-ci (dans notre cas "abcd"). C'est ce qu'on appelle le « stage en chaîne ». Toutes les constantes de chaîne traitées au moment de la compilation sont automatiquement internes à Java. Exemple 2 :
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True
c==dfalse car cils dfont référence à deux objets différents en mémoire (sur le tas). Différents objets ont toujours des références différentes. Ce schéma illustre les deux situations décrites ci-dessus : Traduction : Création d'objets chaîne en Java - Utilisation

2. Chaînes internes au stade de l’exécution du programme

L'auteur remercie LukasEder (le commentaire ci-dessous est le sien) : L'internement de chaînes peut également se produire pendant l'exécution du programme, même si deux chaînes sont créées à l'aide de constructeurs :
String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

3. Quand utiliser des guillemets doubles et quand utiliser des constructeurs

Étant donné que le littéral "abcd" est toujours de type String, l'utilisation d'un constructeur créera un objet supplémentaire inutile. Des guillemets doubles doivent donc être utilisés si vous avez simplement besoin de créer une chaîne. Si vous devez réellement créer un nouvel objet sur le tas, vous devez utiliser un constructeur. Les cas d'utilisation sont présentés ici (original) . (Je fournis le texte traduit ci-dessous. Mais je vous recommande tout de même fortement de vous familiariser avec le code des commentateurs sur ce lien.)

La méthode substring() dans JDK 6 et JDK 7

La méthode substring() dans JDK 6 et JDK 7 Par X Wang La méthode substring(int beginIndex, int endIndex)dans JDK 6 et JDK 7 est différente. Connaître ces différences peut vous aider à mieux utiliser cette méthode. Par souci de facilité de lecture, substring()nous désignerons ci-dessous la syntaxe complète, c'est-à-dire substring(int beginIndex, int endIndex).

1. Que fait substring() ?

La méthode substring(int beginIndex, int endIndex)renvoie une chaîne qui commence par le numéro de caractère beginIndexet se termine par le numéro de caractère endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Sortir:
bc

2. Que se passe-t-il lorsque substring() est appelé ?

Vous savez peut-être qu'en raison de l'immuabilité x, lors de l'attribution à x du résultat de x.substring(1,3), xil pointe vers une toute nouvelle ligne (voir diagramme) : Traduction : Création d'objets chaîne en Java - UtilisationCependant, ce diagramme n'est pas tout à fait correct ; cela ne démontre pas ce qui se passe réellement dans le tas. Ce qui se passe réellement lorsque est appelé substring()est différent dans JDK 6 et JDK 7.

3. substring() dans JDK 6

Le type chaîne est pris en charge par le type tableau char. Dans JDK 6, la classe Stringcontient 3 champs : char value[], int offset, int count. Ils sont utilisés pour stocker le tableau de caractères réel, l'index du premier caractère du tableau, le nombre de caractères de la ligne. Lorsque la méthode est appelée substring(), elle crée une nouvelle ligne, mais la valeur de la variable pointe toujours vers le même tableau sur le tas. La différence entre deux chaînes réside dans leur nombre de caractères et la valeur d'index du caractère de départ dans le tableau. Traduction : Création d'objets chaîne en Java - UtilisationLe code ci-dessous est simplifié et ne contient que les bases pour démontrer le problème.
//JDK 6
String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

4. Problème causé par substring() dans JDK 6

Si vous avez une chaîne TRÈS longue, mais que vous n’en avez besoin que d’une petite partie, que vous obtenez à chaque fois en utilisant substring(). Cela entraînera des problèmes d'exécution, car vous n'avez besoin que d'une petite partie, mais vous devez quand même stocker la chaîne entière. Pour le JDK 6, la solution est le code ci-dessous, qui convertira la chaîne en une véritable sous-chaîne :
x = x.substring(x, y) + ""
L'utilisateur STepeR a formulé une question (voir son commentaire), et il a semblé nécessaire d'ajouter le point 4. "Problème causé substring()dans JDK 6" est un exemple plus détaillé. J'espère que ce sera la réponse et aidera les autres à comprendre rapidement quel est le problème. Voici le code :
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Ainsi, dans le JDK 7 b, les objets сde type a Stringcréés en appelant une méthode substring()sur un objet de type a Stringferont référence à deux tableaux nouvellement créés dans le tas - Lfor b, ongLfor c. Ces deux nouveaux tableaux seront stockés sur le tas LE LONG du tableau d'origine aLongLongStringréférencé par a. Ceux. le tableau d'origine ne disparaît nulle part. Revenons maintenant au JDK 6. Dans le JDK 6, un tas contient un seul tableau aLongLongString. Après avoir exécuté les lignes de code
String b = a.substring(1, 2);
String c = a.substring(2, 6);
les objets bfont référence cau même tableau dans le tas, correspondant à l'objet a: b- aux éléments du 1er indice au 2ème, c- aux éléments du 2ème indice au 6ème (la numérotation commence à 0, rappel). Ceux. Évidemment, tout accès ultérieur aux variables bou à c dans JDK 6 entraînera en fait le « comptage » des éléments souhaités du tableau d'origine dans le tas. Dans JDK 7, tout accès supplémentaire aux variables bou à c entraînera un accès aux tableaux plus petits nécessaires qui ont déjà été créés et « vivants » dans le tas. Ceux. Il est clair que JDK 7 utilise physiquement plus de mémoire dans des situations comme celle-ci. Mais imaginons une option possible : certaines sous-chaînes de la variable sont affectées aux variables b, et à l'avenir tout le monde n'en utilise que - les objets et . Plus personne n'accède simplement à la variable a, il n'y a aucune référence à celle-ci (c'est ce que veut dire l'auteur de l'article). En conséquence, à un moment donné, le garbage collector se déclenche, et (sous la forme la plus générale, bien sûr) nous obtenons 2 situations différentes : JDK 6 : l'objet est détruit (garbage collecté) , MAIS - l'énorme original le tableau dans le tas est vivant ; il est constamment utilisé et . JDK 7 : l'objet a est détruit avec le tableau d'origine dans le tas. Ce moment dans JDK 6 peut entraîner une fuite de mémoire. cabcabc

5. sous-chaîne() dans JDK 7

La méthode a été améliorée dans JDK 7. Dans JDK 7 substring(), il crée en fait un nouveau tableau sur le tas. Traduction : Création d'objets chaîne en Java - Utilisation
//JDK 7
public String(char value[], int offset, int count) {
	//check boundary
	this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	int subLen = endIndex - beginIndex;
	return new String(value, beginIndex, subLen);
}
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION