Głównym powodem skopiować ciąg jest „przyciąć” bagaż, to przyciąć stanowiącego podstawę char tablicę do tylko to, co jest konieczne.
Podstawowa tablica znaków może być zbyt duża, ponieważ podczas tworzenia łańcucha przez wywołanie substring
tablica znaków może być współużytkowana między nową instancją łańcucha a instancją źródłową; przesunięcie wskazuje na pierwszy znak, a długość jest uwzględniona.
Wyrażenie używam, „przyciąć bagaż”, pochodzi z kodem źródłowym String konstruktora kopiującego:
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;
To jest coś, wielu deweloperów zapomnieć i to ważne, ponieważ mały ciąg może zapobiec garbowanie większej tablicy char. Zobacz to pokrewne pytanie, na które już wskazałem: Java not garbage collecting memory. Wielu programistów uważa, że decyzja projektantów Javy, aby użyć tej starej sztuczki optymalizacyjnej, która była znana koderom C, w rzeczywistości przyniosła więcej szkód niż korzyści. Wielu z nas wie o tym, ponieważ byliśmy przez niego pogryzieni i musieliśmy zajrzeć do kodu źródłowego Sun, aby zrozumieć, co się stało ...
Jak zauważa Marko (patrz komentarze poniżej), w OpenJDK, począwszy od wersji Java 7 Update 6 , substring
nie udostępnia już tablicy znaków, a konstruktor String(String)
jest w związku z tym bezużyteczny. Ale wciąż jest szybki (jeszcze szybciej), a ponieważ ta zmiana nie została rozpowszechniona na wszystkich maszynach wirtualnych (i prawdopodobnie nie wszystkich klientach), poleciłbym zachować tę najlepszą praktykę, aby użyć new String(substring)
, gdy stare zachowanie uzasadniało to .
To nie jest "zbyt zlokalizowane", jest to dobre pytanie dla osób znajdujących się później, z bardzo przydatną i informacyjną odpowiedzią. –
Zobacz odpowiedź [this] (http://stackoverflow.com/a/465682/1037210). – Lion
Należy zauważyć, że odpowiedzi na wyżej wymienione podobne pytanie można prawdopodobnie uznać za częściowo przestarzałe. –