1. Comparații

Programatorii trebuie să compare diferite variabile între ele tot timpul. Dar, după cum ați văzut deja, totul nu este atât de simplu.

Numerele întregi sunt foarte ușor de comparat - doar le utilizați ==și ați terminat. Pentru a compara numerele reale , trebuie să comparați diferența lor (sau mai degrabă, valoarea absolută a diferenței) cu un număr foarte mic.

Compararea corzilor este și mai dificilă. Mai presus de toate, acest lucru se datorează faptului că șirurile sunt obiecte. În plus, programatorii doresc adesea ca comparația șirurilor să meargă puțin diferit în funcție de situație.


2. Cum sunt aranjate șirurile de memorie

După cum ați văzut deja, șirurile sunt stocate în memorie diferit de numerele întregi și reale:

Cum sunt aranjate șirurile de memorie

Două blocuri de memorie sunt folosite pentru a stoca șiruri de caractere: un bloc stochează textul în sine (dimensiunea acestuia depinde de dimensiunea textului) în timp ce al doilea bloc (4 octeți) stochează adresa primului bloc.

Deși un programator experimentat ar spune ceva de genul „ String strvariabila stochează o referință la un Stringobiect.


3. Atribuirea referințelor unui șir

Beneficiile acestei abordări devin evidente atunci când trebuie să atribuiți o variabilă șir unei alte variabile șir. Exemplu:

String text = "This is a very important message";
String message = text;

Și iată ce va conține memoria ca rezultat:

Atribuirea referințelor unui șir

După acest tip de operație de atribuire, obiectul Stringrămâne acolo unde a fost și doar adresa sa (o referință la obiect) este copiată în messagevariabilă.


4. Lucrul cu referințe și obiecte

Dar dacă decideți să convertiți un șir în majuscule (litere mari), mașina Java face totul corect: veți ajunge cu două Stringobiecte, iar variabilele textși messagevor stoca referințe, fiecare la propriul obiect.

Exemplu:

String text = "This is a very important message";
String message = text.toUpperCase(); 

Și iată ce va conține memoria ca rezultat:

Lucrul cu referințe și obiecte

Vă rugăm să rețineți că toUpperCase()metoda nu schimbă șirul pe care este apelat. În schimb, creează un șir nou (obiect nou) și returnează o referință la acesta.

Ce zici de un exemplu și mai interesant. Să presupunem că decideți să transmiteți un șir unui Scannerobiect (astfel încât acesta să citească valorile din șir).

Exemplu:

String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();

Puteți afla mai multe despre cum Scannerfuncționează clasa aici .

Acesta este modul în care totul va fi stocat în memorie:

Lucrul cu referințe și obiecte.  Clasa de scaner

În acest caz, un singur Stringobiect rămâne în memorie așa cum a fost - doar referințele la el sunt transmise și stocate în variabile.


5. Compararea referințelor la Stringobiecte

Și, în sfârșit, am ajuns la partea distractivă: compararea șirurilor.

Există doi operatori pe care îi puteți utiliza pentru a compara variabilele șir: ==(egal) și !=(nu este egal). Nu puteți folosi operatorii „mai mare decât”, „mai mic decât” sau „mai mare decât sau egal cu” — compilatorul nu va permite acest lucru.

Dar există o nuanță interesantă aici: ce este de fapt stocat în variabilele șir? Așa este: adrese (referințe) la obiecte. Și aceste adrese vor fi comparate:

String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase(); 

Iată ce va fi în memorie:

Compararea referințelor la obiecte String

Variabilele messageși textse referă la (stochează adresa) aceluiași obiect. Dar variabilele s1și s2stochează referințe la obiecte care sunt foarte asemănătoare, dar distincte.

Și dacă comparați aceste 4 variabile în cod, atunci obțineți următorul rezultat:

Cod Ieșire de consolă
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
System.out.println(text == message);
System.out.println(text == s1);
System.out.println(s1 == s2); 


true  // The addresses are equal
false // The addresses are different
false // The addresses are different