În teoria și practica programării se cunosc diferite moduri
în car se poate face transmiterea argumentelor către o funcție sau
procedură: - transmitere prin valoare: de la programul apelant către funcție (procedură) se transmit valorile argumentelor; - transmitere prin adresa: de la programul apelant către funcție (procedură) se transmit adresele la care se găsesc în memorie valorile argumentelor; - transmitere prin nume: de la programul apelant către funcție (procedură) se transmit numele argumentelor; - transmitere prin referință: de la programul apelant la funcție (procedură) se transmit referințe către argumente. |
În limbajul Java, transmiterea parametrilor (argumentelor)
metodelor se face prin valoare. Aceasta înseamnă că:
- dacă argumentul aparține unui tip de date primitiv, se transmite
chiar valoarea primitivă a argumentului respectiv;
- dacă argumentul aparține unui tip-referință (este instanță a unei
clase), se transmite - de fapt - o referință către un obiect din clasa
respectiva sau dintr-o clasa derivată din aceasta.
Exemplu Să considerăm metoda int indexOf(String str, int fromIndex) din clasa String. Primul argument al acestei metode este o referință la un obiect din clasa String, iar al doilea argument este o valoare primitivă de tip int. În limbajul Java, cei doi parametri str si fromIndex sunt considerați variabile locale ale metodei indexOf, iar transmiterea parametrilor este echivalentă cu operația de atribuire. În consecință, dacă se invocă această metodă sub forma indexOf("abc", 3), variabilei-referință str i se atribuie ca valoare referința la sirul "abc" (și nu insuși șirul "abc", care rămâne la locul lui în memoria dinamică), în timp ce variabilei fromIndex de tip int i se atribuie valoarea primitivă 3. Să considerăm acum că într-un program există instrucțiunile: int k=7, j; String s1="un exemplu de sir", s2="exem"; j=s1.indexOf(s2,k); Evaluarea metodei indexOf va decurge astfel: se transmit de la programul apelant către metoda indexOf valorile argumentelor s2 si k. Numai că s2 este o variabila-referință, deci valoarea ei este referința la șirul "exem" și nu însuși acest șir. În schimb, valoarea variabilei k este chiar valoarea primitivă 7. În consecință, în șirul indicat de s1, se va căuta subșirul a cărui referință este s2, începand căutarea de la poziția de indice 7. |
În teoria programării, argumentele (parametrii) care apar în
declarația unei metode (funcții, proceduri) se numesc parametri
formali, iar valorile prin care se substituie acești parametri
formali la invocarea metodei respective se numesc parametri efectivi.
Astfel, în exemplul de mai sus, str și fromIndex sunt
parametri formali ai metodei indexOf, in timp ce "abc",
3, valoarea lui s2, și valoarea lui k
sunt parametri efectivi.
Consecința faptului că parametrii metodelor se transmit
prin valoare este următoarea: chiar dacă în corpul unei
metode se atribuie unui argument formal al acesteia o nouă
valoare, această atribuire nu modifică valoarea argumentului efectiv
corespunzător din programul apelant. Daca însă, în cazul unui
argument-referință, nu se modifica referința însăși, ci valorile
câmpurilor obiectului indicat de către aceasta, modificarea
respectivă se va transmite și la programul apelant, constituind efectul
lateral al metodei respective.
Metode care întorc o referință la un obiect construit în corpul lorÎn limbajul Java este posibil ca o metodă să întoarcă o referință la un obiect construit în interiorul ei. Un astfel de exemplu este dat în fișierul TestRef.java, care conține următorul program:
În metoda1 se creează prin operatorul new un
nou șir, iar referința str la acesta este "întoarsă" de această
metodă la executarea instrucțiunii return. În metoda2
se creează de asemenea un nou șir, dar referința la acesta se atribuie
argumentului s al metodei. La executarea acestui program se
obțin următoarele rezultate:
Se observă că metoda1 a întors corect referința către șirul "un sir" care a fost creat în interiorul ei. În schimb, metoda2 nu a avut ca efect lateral transmiterea catre variabila-referință sir2 din main a referinței către obiectul "alt sir" creat în această metodă deoarece, după cum s-a arătat anterior, transmiterea parametrilor se face prin valoare și deci modificarea în corpul metodei a valorii parametrului formal s nu afectează valoarea parametrului efectiv str2 prin care acesta a fost substituit la invocarea metodei respective. Metode care au ca argumente și/sau ca valori întoarse referințe la tablouriÎn limbajul Java, tablourile sunt obiecte. În consecință, dacă parametrii formali ai unei metode sunt tablouri, numele lor sunt, de fapt, variabile-referință. De exemplu, în signatura metodei mainmain(String args[]) parametrul formal args[] este o referință la un tablou, ale cărui elemente aparțin clasei String (sunt șiruri de caractere). În consecință, tot ce s-a prezentat în secțiunea anterioară cu privire la folosirea ca parametri formali a variabilelor- referință este valabil și pentru tablouri. Pentru exemplificare, considerăm programul următor, din fișierul TestTab.java.
Rezultatele afișate la executarea acestui program sunt
următoarele:
Urmărind executarea programului, constatăm că: Remarcăm că, la ieșirea din metoda alpha, variabila locală c
este eliminată de pe stiva sistemului. Cu toate acestea, tabloul creat
în metoda alpha și referit de această variabilă locală nu este eliminat
din memorie, deoarece către el indică în continuare variabila-referință q
din metoda main. |