Come devo copiare le stringhe in Java?


199
    String s = "hello";
    String backup_of_s = s;
    s = "bye";

A questo punto, la variabile di backup contiene ancora il valore originale "ciao" (questo a causa dell'immutabilità di String, giusto?).

Ma è davvero sicuro copiare le stringhe con questo metodo (che ovviamente non è sicuro copiare normali oggetti mutabili), o è meglio scriverlo? :

    String s = "hello";
    String backup_of_s = new String(s);
    s = "bye";

In altre parole, qual è la differenza (se presente) tra questi due frammenti?


EDIT: il motivo per cui il primo frammento è sicuro:

Vorrei solo spiegare le cose con un po 'più di dettaglio, basato sulle buone risposte già fornite (che erano essenzialmente incentrate sulla questione della differenza di prestazioni tra i 2 frammenti):

Le stringhe sono immutabili in Java, il che significa che un oggetto String non può essere modificato dopo la sua costruzione. Quindi,

String s = "hello";crea una nuova istanza String e assegna il suo indirizzo a s( sessendo un riferimento all'istanza / oggetto)

String backup_of_s = s;crea una nuova variabile backup_of_se la inizializza in modo che faccia riferimento all'oggetto a cui fa attualmente riferimento s.

Nota: l'immutabilità delle stringhe garantisce che questo oggetto non verrà modificato: il nostro backup è sicuro

Nota 2: il meccanismo di garbage collection di Java garantisce che questo oggetto non verrà distrutto fintanto che viene indicato da almeno una variabile ( backup_of_sin questo caso)

Infine, s = "bye";crea un'altra istanza String (a causa dell'immutabilità, è l'unico modo) e modifica la svariabile in modo che ora faccia riferimento al nuovo oggetto.

Risposte:


141

Poiché le stringhe sono immutabili, entrambe le versioni sono sicure. Quest'ultimo, tuttavia, è meno efficiente (crea un oggetto in più e in alcuni casi copia i dati del personaggio).

Con questo in mente, la prima versione dovrebbe essere preferita.


15
L'immutabilità non ha nulla a che fare con esso. È semplicemente come funzionano i riferimenti agli oggetti. Potrei fornire un esempio StringBuilder equivalente.
GriffeyDog,

1
@BalusC, non riesco a vedere come il nuovo String () potrebbe creare qualcosa nel pool di stringhe della JVM. Solo pool di stringhe e quelli inviati al pool tramite intern () sono nel pool.
Snicolas,

3
@GriffeyDog: sto leggendo la domanda in modo meno letterale. Quello che sto dicendo è che è sicuro dare riferimenti a un oggetto stringa senza timore che qualcuno possa modificare la stringa.
NPE,

2
@GriffeyDog Trovo il tuo commento molto fuorviante: l'immutabilità è ciò che rende sicuro il primo frammento, perché dovresti dire che non ha nulla a che fare con "esso"?
Sébastien,

5
@Sebastien Tutto ciò che sta facendo è riassegnare la variabile sdi riferimento per fare riferimento a un oggetto diverso (il String"ciao"). Ciò non influisce su ciò a cui backup_of_ssi riferisce la variabile di riferimento (il String"ciao"). Come ho detto, potrei fornire un esempio equivalente con StringBuilders, che non sono immutabili. Il mio commento riguarda principalmente l'istruzione OPs: a questo punto, la variabile di backup contiene ancora il valore originale "ciao" (questo a causa dell'immutabilità di String, giusto?).
GriffeyDog,

22

Le stringhe sono oggetti immutabili in modo da poterle copiare semplicemente copiando il riferimento ad esse, poiché l'oggetto a cui si fa riferimento non può cambiare ...

Quindi puoi copiare come nel tuo primo esempio senza alcun problema:

String s = "hello";
String backup_of_s = s;
s = "bye";

10

La tua seconda versione è meno efficiente perché crea un oggetto stringa aggiuntivo quando semplicemente non è necessario.

Immutabilità significa che la tua prima versione si comporta come ti aspetti ed è quindi l'approccio da preferire.


0

Anche il secondo caso è inefficiente in termini di pool di stringhe, è necessario chiamare esplicitamente intern () sul riferimento di ritorno per renderlo interno.


-16
String str1="this is a string";
String str2=str1.clone();

Che ne dici di copiare in questo modo? Penso che ottenere una nuova copia sia migliore, in modo che i dati di str1non vengano influenzati quando str2vengono referenziati e modificati in ulteriori azioni.


3
Stringè immutabile. clonare le stringhe non ha molto senso.
Vladimir
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.