Non possiamo essere sicuri di cosa stessero realmente pensando i progettisti Java durante la progettazione, String
ma possiamo solo concludere queste ragioni sulla base dei vantaggi che otteniamo dall'immutabilità delle stringhe, alcune delle quali sono
1. Esistenza del pool di costanti di stringhe
Come discusso nell'articolo Perché String è memorizzato nell'articolo String Constant Pool , ogni applicazione crea troppi oggetti stringa e al fine di salvare JVM dalla prima creazione di molti oggetti stringa e quindi dalla loro immondizia. JVM memorizza tutti gli oggetti stringa in un'area di memoria separata chiamata Pool costante di stringhe e riutilizza gli oggetti da quel pool memorizzato nella cache.
Ogni volta che creiamo una stringa JVM letterale per prima cosa vede se quel letterale è già presente nel pool costante o meno e se è presente, un nuovo riferimento inizierà a puntare allo stesso oggetto in SCP.
String a = "Naresh";
String b = "Naresh";
String c = "Naresh";
Supra oggetto stringa esempio con valore Naresh
andranno creato nel SCP sola volta e ogni riferimento a
, b
, c
punterà allo stesso oggetto ma se si cerca di apportare cambiamenti in a
es a.replace("a", "")
.
Idealmente, a
dovrebbe avere valore Nresh
ma b
, c
dovrebbe rimanere invariato perché come utente finale stiamo effettuando la modifica a
solo. E sappiamo a
, b
, c
tutti stanno indicando lo stesso oggetto quindi se facciamo un cambiamento a
, altri dovrebbe anche riflettere il cambiamento.
Ma l'immutabilità delle stringhe ci salva da questo scenario e, a causa dell'immutabilità dell'oggetto stringa, l'oggetto stringa Naresh
non cambierà mai. Pertanto, quando apportiamo modifiche a
anziché modifiche nell'oggetto stringa, Naresh
JVM crea un nuovo oggetto assegnandolo a
e quindi apportando le modifiche in tale oggetto.
Quindi il pool di stringhe è possibile solo a causa dell'immutabilità di String e se String non fosse stato immutabile, la memorizzazione nella cache degli oggetti stringa e il loro riutilizzo non avrebbero possibilità perché qualsiasi variabile avrebbe cambiato il valore e danneggiato altri.
Ed è per questo che è gestito da JVM in modo molto speciale e ha ricevuto un'area di memoria speciale.
2. Sicurezza del filo
Un oggetto viene chiamato thread-safe quando più thread ci stanno operando, ma nessuno di essi è in grado di corromperne lo stato e l'oggetto mantiene lo stesso stato per ogni thread in qualsiasi momento.
Dato che un oggetto immutabile non può essere modificato da nessuno dopo la sua creazione, il che rende ogni oggetto immutabile sicuro per impostazione predefinita. Non è necessario applicare alcuna misura di sicurezza del thread come la creazione di metodi sincronizzati.
Quindi, a causa della sua natura immutabile, l'oggetto stringa può essere condiviso da più thread e anche se viene manipolato da molti thread non cambierà il suo valore.
3. Sicurezza
In ogni applicazione, è necessario passare diversi segreti, ad esempio nome utente \ password, URL di connessione e, in generale, tutte queste informazioni vengono passate come oggetto stringa.
Supponiamo ora che String non sarebbe stato immutabile in natura, quindi causerebbe una grave minaccia alla sicurezza dell'applicazione perché questi valori possono essere modificati e se è consentito, questi potrebbero essere modificati a causa di un codice scritto erroneamente o di qualsiasi altra persona che avere accesso ai nostri riferimenti variabili.
4. Caricamento classe
Come discusso in Creazione di oggetti tramite Reflection in Java con Esempio , possiamo usare il Class.forName("class_name")
metodo per caricare una classe in memoria che chiama nuovamente altri metodi per farlo. E anche JVM utilizza questi metodi per caricare le classi.
Ma se vedi chiaramente tutti questi metodi accetta il nome della classe come oggetto stringa, quindi le stringhe vengono utilizzate nel caricamento della classe java e l'immutabilità garantisce la sicurezza da cui viene caricata la classe corretta ClassLoader
.
Supponiamo che String non sia immutabile e stiamo provando a caricare i java.lang.Object
quali vengono cambiati org.theft.OurObject
nel mezzo e ora tutti i nostri oggetti hanno un comportamento che qualcuno può usare per cose indesiderate.
5. HashCode nella cache
Se eseguiremo operazioni correlate all'hash su qualsiasi oggetto, dovremo sovrascrivere il hashCode()
metodo e provare a generare un hashcode accurato utilizzando lo stato dell'oggetto. Se lo stato di un oggetto viene modificato, significa che dovrebbe cambiare anche il suo hashcode.
Poiché String è immutabile, quindi il valore di un oggetto stringa non verrà mai modificato, il che significa che anche il suo hashcode non cambierà, dando alla classe String l'opportunità di memorizzare nella cache il suo hashcode durante la creazione dell'oggetto.
Sì, l'oggetto String memorizza nella cache il suo hashcode al momento della creazione dell'oggetto, il che lo rende il candidato ideale per le operazioni correlate all'hash perché non è necessario calcolare nuovamente l'hashcode che ci fa risparmiare un po 'di tempo. Questo è il motivo per cui String è usato principalmente come HashMap
chiavi.
Maggiori informazioni sul motivo per cui String è immutabile e finale in Java .