Gli oggetti String sono particolari, perché è possibile scrivere una stringa come "literal" nel sorgente. La domanda che ci si può porre è: se scrivo una stringa "hello" in un sorgente, che cosa è e dove viene messa??
Le stringhe literal vengono messe dal compilatore in una area di memoria speciale chiamata "String constant pool" o più semplicemente "constant pool". Ogni stringa literal è a tutti gli effetti un oggetto di classe String, trattata solo in maniera particolare.
Veniamo a degli esempi che possono chiarire la questione.
String s1 = "hello";
String s2 = "hello";
System.out.println (s1 == s2); // stampa "true"
In questo caso nel constant pool c'è 1 solo oggetto "hello", il compilatore si accorge che sono la stessa stringa e mette nel pool 1 solo oggetto. I due reference sono quindi esattamente uguali e pertanto una comparazione dei reference dà come risultato true.
Altro esempio:
String s1 = new String ("hello");
String s2 = new String ("hello");
System.out.println (s1 == s2); // stampa "false"
In questo caso quando si raggiunge la terza linea, gli oggetti in ballo sono ben 3. L'oggetto "hello" della stringa literal (nel constant pool) e 2 oggetti String allocati sul "heap" a runtime e che hanno lo stesso contenuto (come sequenza di caratteri) della stringa literal.
I reference s1 e s2 sono diversi, perché gli oggetti sono stati istanziati con new e pertanto sull'heap ci sono 2 oggetti String ben distinti.
Questa è la realtà delle cose nella gestione delle stringhe in Java.
EDIT: per tornare alla questione iniziale del thread "Dog d = new Dog() crea due oggetti?" la risposta semplicemente è -no-. Con new si istanzia sempre e solo 1 oggetto.

Rispondi quotando