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:
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
str
variabila stochează o referință la un String
obiect.
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:
După acest tip de operație de atribuire, obiectul String
rămâne acolo unde a fost și doar adresa sa (o referință la obiect) este copiată în message
variabilă.
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ă String
obiecte, iar variabilele text
și message
vor 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:
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 Scanner
obiect (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 Scanner
funcționează clasa aici .
Acesta este modul în care totul va fi stocat în memorie:
În acest caz, un singur String
obiect 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 String
obiecte
Ș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:
Variabilele message
și text
se referă la (stochează adresa) aceluiași obiect. Dar variabilele s1
și s2
stochează 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ă |
---|---|
|
|
GO TO FULL VERSION