Perché gli oggetti 'String' sono immutabili con un costruttore esplicito in java? [duplicare]

0

Ha senso rendere immutabili gli oggetti class String con le seguenti dichiarazioni, perché condividono la stessa archiviazione nel pool comune.

String str1 = "abc";
String str2 = "abc";

Ma non sono sicuro, se ha senso avere oggetti class String immutabili con le seguenti dichiarazioni esplicite del costruttore, perché non condividono la stessa memoria in heap.

String str3 = new String("def");
String str4 = new String("def");

Quindi, se il contenuto di un oggetto class String deve essere modificato di frequente, si consiglia di imparare class StringBuffer e class StringBuilder .

Ha senso sapere, qual è la ragione per cui class String è stato progettato per mantenere il contenuto immutabile con un costruttore esplicito?

    
posta overexchange 28.11.2014 - 06:28
fonte

6 risposte

9

Ovviamente ha senso.

Quando ottieni il valore non ti interessa sapere come è stato costruito.

Non avrebbe senso se l'immutabilità dipenda dal modo in cui un oggetto è stato costruito:

"abc" immutable, new String("def") mutable. Creerebbe un casino.

    
risposta data 28.11.2014 - 07:49
fonte
3

Le stringhe Java devono essere immutabili perché il modello di sicurezza di Java dipende dal valore di esse che non cambiano tra di loro, ispezionate da un'istanza di SecurityManager e consumate da qualsiasi parte del runtime protette da SecurityManager.

Ad esempio, se hai un SecurityManager sul tuo thread ed esegui:

String str = new String ("innocent.txt");
new FileReader(str);

ciò che accade è che il nome del file viene controllato chiamando il metodo canRead del gestore di sicurezza e solo se questo consente l'accesso al file aperto.

Ma se potessimo avviare un altro thread in grado di modificare la stringa in un valore che non sarebbe consentito dal gestore della sicurezza tra la chiamata a canRead e il file che si sta aprendo, potremmo sovvertire le operazioni di sicurezza e preforme che stiamo non dovrebbe essere permesso di fare.

Una soluzione alternativa sarebbe quella di creare copie difensive di qualsiasi stringa critica per la sicurezza, ma questa sarebbe (1) soggetta a errori e (2) rendere il runtime meno efficiente.

    
risposta data 28.11.2014 - 09:23
fonte
2

L'immutabilità per le stringhe ha molti vantaggi anche con un costruttore esplicito (sono sicuro che li conosci già: copie economiche, senza effetti collaterali, semantica del valore). Il costruttore esplicito è esattamente ciò che tutti si aspettano di essere disponibili, senza di esso dovremmo sempre scrivere qualcosa di brutto come

 String s = (new StringBuilder("abc").toString());

L'unica avvertenza, in cui la semantica del valore classico fallisce, è il punto che hai richiesto: con

String str3 = new String("def");
String str4 = new String("def");

il test di uguaglianza str3==str4 fallirà (uno deve usare equal ), qualcosa che ci si aspetterebbe di lavorare per la semantica del valore classico.

Quindi il difetto di progettazione qui non è né l'immutabilità né il fatto che ci sia un costruttore esplicito per le stringhe, ma solo il fatto che i creatori di Java non hanno progettato la lingua in un modo == funziona come previsto. Ma questo è un piccolo prezzo da pagare per non avere tutte le stringhe costruite dalla noiosa riga del costruttore di stringhe sopra.

    
risposta data 28.11.2014 - 07:50
fonte
1

Il costruttore public String(String original) è un costruttore di copie . Il suo unico scopo è creare una copia di un oggetto String.

Poiché String è immutabile, è raro che le copie siano necessarie. Questo è stato trattato in il Javadoc di questo costruttore . Tuttavia, poiché String è una classe principale e viene utilizzata ovunque, potrebbero esserci alcuni casi speciali che richiedono la copia di una stringa.

La classe String ha molti costruttori che sono raramente necessari nella maggior parte delle applicazioni. In realtà, l'utilizzo di qualsiasi costruttore String per creare un nuovo oggetto String non è un modo comune per ottenere una stringa nella maggior parte delle applicazioni.

    
risposta data 28.11.2014 - 10:08
fonte
0

Sono immutabili e quindi si comportano come valori. Puoi passare il riferimento alla stringa e non devi temere che qualunque sia il codice che hai passato possa cambiarlo.

    
risposta data 28.11.2014 - 06:59
fonte
0

Il costruttore esplicito è un cosiddetto costruttore di copie. È destinato al raro caso in cui è necessario assicurarsi di ricevere una nuova istanza String invece di una pool. La stringa appena creata è ancora immutabile, poiché non è possibile modificare il riferimento alla stringa passata.

    
risposta data 28.11.2014 - 10:25
fonte

Leggi altre domande sui tag