1. Confronti
I programmatori devono confrontare continuamente variabili diverse tra loro. Ma, come hai già visto, non tutto è così semplice.
I numeri interi sono molto facili da confrontare: basta usarli ==
e il gioco è fatto. Per confrontare i numeri reali , devi confrontare la loro differenza (o meglio, il valore assoluto della differenza) con un numero molto piccolo.
Confrontare le stringhe è ancora più difficile. Soprattutto perché le stringhe sono oggetti. Inoltre, i programmatori spesso desiderano che il confronto tra stringhe avvenga in modo leggermente diverso a seconda della situazione.
2. Come sono disposte le stringhe in memoria
Come hai già visto, le stringhe vengono memorizzate in memoria in modo diverso rispetto agli interi e ai numeri reali:
Due blocchi di memoria vengono utilizzati per memorizzare le stringhe: un blocco memorizza il testo stesso (la sua dimensione dipende dalla dimensione del testo) mentre il secondo blocco (4 byte) memorizza l'indirizzo del primo blocco.
Sebbene un programmatore esperto direbbe qualcosa come "la String
str
variabile memorizza un riferimento a un String
oggetto.
3. Assegnazione di riferimenti a una stringa
I vantaggi di questo approccio diventano evidenti quando è necessario assegnare una variabile stringa a un'altra variabile stringa. Esempio:
String text = "This is a very important message";
String message = text;
Ed ecco cosa conterrà la memoria come risultato:

Dopo questo tipo di operazione di assegnazione, l' String
oggetto rimane dov'era e solo il suo indirizzo (un riferimento all'oggetto) viene copiato nella message
variabile.
4. Lavorare con riferimenti e oggetti
Ma se decidi di convertire una stringa in maiuscolo (lettere maiuscole), la macchina Java fa tutto bene: ti ritroverai con due String
oggetti e le variabili text
e message
memorizzeranno i riferimenti, ciascuno al proprio oggetto.
Esempio:
String text = "This is a very important message";
String message = text.toUpperCase();
Ed ecco cosa conterrà la memoria come risultato:
Si noti che il toUpperCase()
metodo non modifica la stringa su cui viene chiamato. Invece, crea una nuova stringa (nuovo oggetto) e restituisce un riferimento ad essa.
Che ne dici di un esempio ancora più interessante. Diciamo che decidi di passare una stringa a un Scanner
oggetto (in modo che legga i valori dalla stringa).
Esempio:
String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();
Puoi saperne di più su come Scanner
funziona la classe qui .
Ecco come verrà tutto memorizzato:
In questo caso, un singolo String
oggetto rimane in memoria così com'era: solo i riferimenti ad esso vengono passati e archiviati nelle variabili.
5. Confrontare i riferimenti agli String
oggetti
E finalmente, siamo arrivati alla parte divertente: il confronto tra stringhe.
Esistono due operatori che è possibile utilizzare per confrontare le variabili stringa: ==
(uguale) e !=
(diverso). Non è possibile utilizzare gli operatori "maggiore di", "minore di" o "maggiore o uguale a" — il compilatore non lo consentirà.
Ma c'è una sfumatura interessante qui: cosa viene effettivamente memorizzato nelle variabili stringa? Esatto: indirizzi (riferimenti) a oggetti. Ed è questi indirizzi che verranno confrontati:
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
Ecco cosa rimarrà in memoria:
Le variabili message
e text
si riferiscono a (memorizzano l'indirizzo di) lo stesso oggetto. Ma le variabili s1
e s2
memorizzano riferimenti a oggetti molto simili ma distinti.
E se confronti queste 4 variabili nel codice, ottieni il seguente risultato:
Codice | Uscita console |
---|---|
|
|
GO TO FULL VERSION