Originariamente inviato da mattew80
Codice PHP:
String s = new String("Hello");
Esiste anche una variante sintetica per la creazione di un oggetto String, che è la seguente:
Codice PHP:
String s = "Hello";
C'è una differenza sostanziale: nel primo caso ci sono 2 oggetti, nel secondo solo 1.
Le stringhe "literal" (letterali) vengono messe in un "constant pool". Nel primo caso passi una stringa literal al costruttore di String e poi viene creato un nuovo String con lo stesso contenuto della stringa literal.
Originariamente inviato da mattew80
Nel momento in cui faccio:
Codice PHP:
s = " World";
in realtà non ho modificato l'oggetto originario che conteneva la stringa
hello, bensì ho creato un nuovo oggetto String, facendo in modo che l'oggetto precedente (
hello) venisse distrutto tramite il garbage collector e che la variabile reference
s faccia ora riferimento ad una nuova area di memoria in cui si trova un nuovo oggetto di tipo
String inizializzato con la stringa
world.
Precisazione: le stringhe "literal" non vengono mai garbage-collected.
Originariamente inviato da mattew80
L'oggetto
String, quindi, non subisce nessun tipo di modifica, in quanto il valore con cui l'ho inizializzato nel costruttore è immutabile.
No, la mutabilità o immutabilità di un oggetto non dipende dal tipo di dato usato o da cosa si passa nel costruttore.
Dipende da come è fatta la classe, cioè da come le variabili di istanza sono accessibili e da quali metodi ci sono e da cosa fanno con lo stato dell'oggetto.
La seguente classe definisce oggetti immutabili:
codice:
class Intero
{
private int val;
public Intero (int v) { val = v; }
public int getValore () { return val; }
}
Il motivo è semplice: una volta creato un oggetto Intero, non ci sono metodi per modificare il suo stato e inoltre la variabile 'val' non è accessibile direttamente dall'esterno.
Quello che segue adesso è mutabile:
codice:
class Intero
{
private int val;
public Intero (int v) { val = v; }
public int getValore () { return val; }
public void addValore (int a) { val += a; }
}
Ora con il metodo addValore posso alterare lo stato dell'oggetto, quindi è mutabile.
Quello che segue adesso è nuovamente immutabile, ha un metodo addValore che però non modifica lo stato ma bensì crea e restituisce un nuovo Intero modificato:
codice:
class Intero
{
private int val;
public Intero (int v) { val = v; }
public int getValore () { return val; }
public Intero addValore (int a) { return new Intero (val+a); }
}
Quest'ultima è la stessa, identica, situazione della classe String.
Originariamente inviato da mattew80
Discorso analogo per i metodi della classe
String, come
concat, i quali non modificano le strighe, bensì ritornano un nuovo oggetto
String usando, presumibilmente, valori temporanei per la modifica onde evitare di perdere la stringa originaria.
Sì ma la stringa originale non viene persa ... non c'è questo "pericolo". La stringa è lo stato dell'oggetto e come si è detto, non viene toccato assolutamente.
Originariamente inviato da mattew80
Discorso inverso per i tipi elementari, come gli
int, i cui valori vengono effettivamente modificati durante le assegnazioni.
Anche le variabili di tipo reference vengono modificate durante la assegnazione. Ma in questo caso è il valore del reference a cambiare.