W Javie zawsze stosowany jest mechanizm pass-by-value (przekazywanie przez wartość), ale istnieje szczególna cecha dla obiektów:
Dlatego zmiana pól obiektu wewnątrz metody wpływa na oryginalny obiekt, natomiast próba przypisania nowej referencji do zmiennej wewnątrz metody — nie ma wpływu na oryginalny obiekt. Często myli się to z pass-by-reference, ale Java nie wspiera pass-by-reference!
Przykład:
void changePrimitive(int a) { a = 10; } void changeObject(Point p) { p.x = 10; } int num = 5; changePrimitive(num); // num nadal 5 Point pt = new Point(1, 2); changeObject(pt); // teraz pt.x == 10
Ważne! Jeśli wewnątrz metody przypiszemy p = new Point(100, 200) — oryginalny obiekt poza metodą się nie zmieni. Zmienia się pole obiektu, a nie jego referencja!
Pytanie: Czy można zmienić obiekt przekazany jako argument w metodzie tak, aby poza metodą zmienna-referencja wskazywała na nowy obiekt?
Odpowiedź: Nie, nie można. Przypisanie nowej referencji argumentowi wewnątrz metody wpływa tylko na kopię referencji, która znika po wyjściu z metody. Poza metodą zmienna-argument wskazuje na poprzedni obiekt.
void reassign(Point p) { p = new Point(100, 200); // tylko lokalnie! } Point pt = new Point(5, 5); reassign(pt); // pt wciąż (5, 5)
Historia
W dużym systemie finansowym zaimplementowano API, które "zwracało" zmiany w obiekcie, modyfikując referencję wewnątrz metody. W rezultacie po wyjściu z metody zmiany nie były odzwierciedlane. Konieczne było całkowite przemyślenie części logiki, aby wyraźnie rozdzielić mutację i zwracanie nowych obiektów.
Historia
Przy próbie zaimplementowania swap dla dwóch obiektów w Java metodą
swap(A a, B b)programista przekazywał referencje i zmieniał je miejscami wewnątrz metody. To nie zadziałało. Należało albo zwrócić wynik, albo użyć kontenerów-tablic. Nieznajomość pass-by-value prowadziła do nieprawidłowej wymiany obiektów.
Historia
Jeden z uczestników projektu migrował logikę z C++ i oczekiwał zachowania pass-by-reference. W rezultacie metody przestały działać poprawnie: zmiany wewnątrz metody nie "wychodziły" na zewnątrz. Konieczne było pilne przepisanie krytycznych fragmentów kodu, co zajęło znaczną ilość czasu.