Obiectele ca parametri ai metodelor
Obiectele claselor, la fel ca și datele de tipuri primitive, pot fi transmise ca parametri în metode. Cu toate acestea, în acest caz există o particularitate - atunci când se transmit obiecte, se transmite o copie a referinței către zona de memorie unde este localizat obiectul. Să analizăm un exemplu simplu. Să presupunem că avem următoarea clasă Person:
public class Program{
public static void main(String[] args) {
Person kate = new Person("Kate");
System.out.println(kate.getName()); // Kate
changeName(kate);
System.out.println(kate.getName()); // Alice
}
static void changeName(Person p){
p.setName("Alice");
}
}
class Person{
private String name;
Person(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
Aici, în metoda changeName, se transmite un obiect Person, al cărui nume este modificat. Deoarece în metodă se transmite o copie a referinței către zona de memorie în care se află obiectul Person, variabila kate și parametrul p din metoda changeName vor indica același obiect în memorie. Prin urmare, după executarea metodei, obiectului kate, transmis în metodă, i se va schimba numele din "Kate" în "Alice".
Acest caz trebuie diferențiat de următorul:
public class Program{
public static void main(String[] args) {
Person kate = new Person("Kate");
System.out.println(kate.getName()); // Kate
changePerson(kate);
System.out.println(kate.getName()); // Kate - nicio modificare
// kate păstrează referința la obiectul vechi
}
static void changePerson(Person p){
p = new Person("Alice"); // p indică către un nou obiect
p.setName("Ann");
}
static void changeName(Person p){
p.setName("Alice");
}
}
class Person{
private String name;
Person(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
În metoda changePerson se transmite, de asemenea, o copie a referinței la obiectul Person. Cu toate acestea, în cadrul metodei, nu modificăm valorile individuale ale obiectului, ci recreăm un obiect nou folosind constructorul și operatorul new. Ca urmare, în memorie va fi alocat un nou spațiu pentru noul obiect Person, iar referința către acest obiect va fi atribuită parametrului p:
static void changePerson(Person p){
p = new Person("Alice"); // p indică către un nou obiect
p.setName("Ann"); // se modifică noul obiect
}
Astfel, după crearea noului obiect Person, parametrul p și variabila kate din metoda main vor păstra referințe la obiecte diferite. Variabila kate, transmisă în metodă, va continua să păstreze referința la obiectul vechi din memorie. Prin urmare, valoarea sa nu se schimbă.