La principale raison de copier une chaîne de caractères est de "coupez le bagage" qui consiste à réduire le tableau de chars sous-jacent à ce qui est nécessaire.
Le tableau de chars sous-jacent peut principalement être trop grand car lorsque vous créez une chaîne de caractères en appelant substring
le tableau de caractères peut être partagé entre la nouvelle instance de chaîne et l'instance de chaîne source ; un décalage pointe vers le premier caractère et la longueur est incluse.
L'expression que j'utilise, "coupez le bagage" est tiré du code source du constructeur de copie de chaîne :
164 public String(String original) {
165 int size = original.count;
166 char[] originalValue = original.value;
167 char[] v;
168 if (originalValue.length > size) {
169 // The array representing the String is bigger than the new
170 // String itself. Perhaps this constructor is being called
171 // in order to trim the baggage, so make a copy of the array.
172 int off = original.offset;
173 v = Arrays.copyOfRange(originalValue, off, off+size);
174 } else {
175 // The array representing the String is the same
176 // size as the String, so no point in making a copy.
177 v = originalValue;
178 }
179 this.offset = 0;
180 this.count = size;
181 this.value = v;
C'est une chose que beaucoup de développeurs oublient et qui est importante car une petite chaîne de caractères peut empêcher le gaspillage d'un tableau de caractères plus grand. Voir cette question connexe où j'ai déjà souligné ce point : Java ne récupère pas la mémoire . De nombreux développeurs estiment que la décision des concepteurs de Java d'utiliser cette vieille astuce d'optimisation familière aux codeurs C a, en fait, fait plus de mal que de bien. Beaucoup d'entre nous le savent parce que nous en avons fait les frais et que nous avons dû consulter le code source de Sun pour comprendre ce qui s'est passé...
Comme le souligne Marko (voir les commentaires ci-dessous), dans OpenJDK, à partir de java 7 Update 6, substring
ne partage plus le tableau de chars et la fonction String(String)
est donc inutile. Mais c'est toujours rapide (même plus rapide en fait) et comme ce changement n'a pas été propagé à toutes les VM (et probablement pas à tous vos clients), je recommanderais de garder cette meilleure pratique pour utiliser new String(substring)
alors que l'ancien comportement le justifiait.