Dlaczego gdy przekazujemy obiekty do metody, to przy np. zamianie ich miedzy sobą po wyjściu z metody te obiekty są nienaruszone (czyli podobnie jak ze zmiennymi - przekazywana do funkcji była ich kopia, tzn. kopia referencji?)
A jak jest ta zamiana dokonywana nie w metodzie tylko w ciele main() to zamiana ma miejsce ? Poniżej mój testowy kod.
import java.util.*;
public class Test {
int a;
String napis;
//konstruktor
public Test(){
a = 1;
napis = "Napis";
}
//konstruktor nr2 z argumentami
public Test(int a, String n){
this.a = a;
this.napis = n;
}
public int getA(){
return this.a;
}
public String getNapis(){
return this.napis;
}
//#1 metody nie moga modyfikowac parametrow liczbowych
public static void changeZmienna(int x){
//proba zmiany zmiennej o nazwie zmienna (ale sie nie uda, bo do x jest kopiowana wartosc, która ginie po wyjściu z funkcji)
x = x+1;
}
//#2 metody moga modyfikowac stan obiektu - jesli jest utworzony obiekt
public void setA(int x){
//proba zmiany skladowej a - uda sie, praca na obiekcie
this.a = x;
}
public static void zamienObiekty(Test a, Test b){
Test t = a;
a=b;
b=t;
System.out.println("Przed opuszczeniem zamienObiekty: t1="+a.getNapis()+", t2="+b.getNapis());
}
public static void main(String[] args){
int zmienna = 666;
System.out.println("Test #1: przed - "+zmienna);
changeZmienna(zmienna);
System.out.println("Test #1: po - "+zmienna);
Test t1 = new Test();
System.out.println("Test #2: przed - "+t1.getA());
t1.setA(4);
System.out.println("Test #2: po - "+t1.getA());
Test t2 = new Test(2,"Napis2");
Test tmp = t1;
t1 = t2; //a dlaczego TUTAJ DZIALA - zmienna referencyjna t1 wskazuje teraz na obszar wczesniej wskazywany przez t2
t2 = tmp; //i na odwrot
System.out.println(t1.getNapis()); //t1 pokazuje na to co bylo na poczatku w t2
System.out.println(t2.getNapis()); //i na odwrot -- DLACZEGO TUTAJ NIE DZIALA?
zamienObiekty(t1,t2);
System.out.println("Po opuszczeniu zamienObiekty: t1="+t1.getNapis()+", t2="+t2.getNapis());
}
}
Tzn. mam na myśli to, że przecież do funkcji przekazuję jakaś zmienna referencyjną, czyli referencje do jakiegoś miejsca w pamięci. Domyślam się, że musiałbym przy wyjściu robić returna i przypisywać do czegoś, żeby tego co było wykonywane w metodzie nie utracić. No a w main() również kopiuję referencję (wskazywanie na jakiś obszar pamięci, na jakąś wartość) i przypisuję ją do innej zmiennej referencyjnej. I tutaj ta podmiana działa.
W c++ przy przekazywaniu referencji do funkcji wszystko było ok w tym sensie, że operowało się właśnie na danej wartości (a nie na jej kopii).