Pass-by-value, pass-by-reference, memory model

Pass-by-value, pass-by-reference, memory model
GA
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

Przeczytałem kilka artykułów, odpowiedzi ze Stacka, obejrzałem kilka filmików na YT i nadal nie mam pewności czy dobrze rozumiem jak działa pamięć w Javie i czy Java jest pass-by-value cyz pass-by-reference, tak więc prosiłbym o potwierdzenie ;)

  • Mamy dwa typy danych - primitives i reference types.
  • Te pierwsze, jeżeli stworzone lokalnie, są przechowywane na stosie. Poniższy kod stworzy dwa osobne elementy na stosie.
Kopiuj
int a = 3;
int b = a;

Jeżeli napiszę teraz b = 5, zmienie tylko wartość zmiennej b, zmienna a pozostanie równa 3.

  • Te drugie, na stosie przechowywują wskaźnik do faktycznej wartości obiektu na stercie. Poniższy kod stworzy na stosie dwa wskaźniki do tej samej wartości na stercie:
Kopiuj
User john = new User("john");
User jack = john;

Oznacza to, że jack.name = "Jack" spowoduje zmianę w zmiennej john i jack

  • Przekazanie czegokolwiek do funkcji, powoduje stworzenie kopii przekazanej wartości, tak więc wszystkie zmiany jakie zrobie wewnątrz funkcji, nie zmodyfikują oryginalnego argumentu. Jednakże, analogiczne jak w powyższych przykładach, przekazanie primitywnego typu, powoduje stworzenie jego kopii na stosie, więc faktycznie zmiana czegoś wewnątrz funkcji wpłynie tylko na kopie. Z drugiej strony, przekazanie obiektu, spowoduje stworzenie na stosie kopii wskaźnika, który jednak wskazuje na tę samą referencę na stercie. Dlatego też, zmiana właściwości kopii tego obiektu, zostanie również zaaplikowana do oryginalnego obiektu.

  • Jako, że Java jest pass-by-value, oznacza to że value to adres konkretnego bytu, a reference to jego faktyczna wartość?

  • Co faktycznie jest przechowywane na stosie w przypadku typów primitywnych?

TR
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 lata
  • Postów:731
0

tutaj chyba jest jasno wytłumaczone: https://community.oracle.com/tech/developers/discussion/2110675/pass-by-reference-or-pass-by-value

There is no such thing as pass by reference in Java. Once again you do not seem to understand that the object is not passed. The variable "obj" is not an object, it is a reference. The value is copied, this is pass by value. Because it is copied both variables point to the same instance of class A. You are then modifying that object's instance variables, you're not actually changing the variable passed.


musica curat corpus at animam
Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około godziny
1

@Gazel: Prawie dobrze. Wskaźnik to mniej więcej to samo co referencja w tym sensie, że oba zawierają adres. W Javie nie używa się pojęcia wskaźnika, jest tylko pojęcie referencji do obiektu (ale jak ktoś użyje słowa wskaźnik to też wiadomo, że chodzi o to samo co z referencją). Z tego względu stwierdzenie typu:

Z drugiej strony, przekazanie obiektu, spowoduje stworzenie na stosie kopii wskaźnika, który jednak wskazuje na tę samą referencę na stercie.

.. jest co najmniej błędne. Referencja wskazuje na instancję obiektu na stercie. Takiej terminologii się w Javie używa.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit
GA
  • Rejestracja:ponad 4 lata
  • Ostatnio:około rok
  • Postów:68
0

@Wibowit:

.. jest co najmniej błędne. Referencja wskazuje na instancję obiektu na stercie. Takiej terminologii się w Javie używa.

Właśnie to mnie myli ;)

  • Czyli na stosie trzymamy referencje (adres) obiektu który znajduje się na stercie?
  • Do fukcji przekazujemy referencje (adres) obiektu, następnie tworzona jest kopia tej referencji, która jednak nadal odnosi się do tego samego obiektu na stercie?

Czemu więc to się nazywa pass-by-value, skoro przekazujemy referencje... :D ?

edytowany 1x, ostatnio: Gazel
stivens
Ehh. Zeby pokazac mniej najpierw trzeba pokazac wiecej. Zaraz wstawie przyklad z C++ i pass-by-reference
RA
Bo możesz zmienić w metodzie wartość tej zmiennej otrzymanej (na np. new Object()) i to nie wpłynie na zmienną podaną do metody? ztcp w c++ da się
stivens
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 godziny
2

C++, pass-by-reference

https://replit.com/@stivens/DeadInterestingInsurance#main.cpp

Java, pass-by-value (w szczegolnym przypadku wartoscia jest referencja)

https://replit.com/@stivens/ForcefulInternalRuntimes#Main.java


Roznice chyba widac po wywolaniu? :)


λλλ
edytowany 3x, ostatnio: stivens
Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około godziny
8

Czyli na stosie trzymamy referencje (adres) obiektu który znajduje się na stercie?

Tak

Do fukcji przekazujemy referencje (adres) obiektu, następnie tworzona jest kopia tej referencji, która jednak nadal odnosi się do tego samego obiektu na stercie?

Tak

Czemu więc to się nazywa pass-by-value, skoro przekazujemy referencje... :D ?

Bo przekazujesz referencję przez wartość :] W C/ C++/ Ruście/ etc można mieć wskaźnik do wskaźnika do wskaźnika etc, a więc można np. przekazać wskaźnik przez wskaźnik i czasami tak się robi przy wywołaniach funkcji bibliotecznych.

Inaczej mówiąc:

  • pass-by-value oznacza, że argument jest kopiowany - jeśli jest to prymityw to kopiujemy prymityw, jeśli jest to referencja to kopiujemy referencję. W Javie nie ma zmiennych przechowujących obiekty (przynajmniej tych z tożsamością, bo po wprowadzeniu Project Valhalla będzie można zrobić obiekt prymitywny, ale to przyszłość), więc nie ma kopiowania obiektów.
  • pass-by-reference oznacza, że argument nie jest kopiowany, a za to w docelowej metodzie otrzymujemy referencję do niego i możemy dzięki temu modyfikować oryginalny argument. W Javie tego nie ma. Jeśli zrobię wywołanie metodaA(lokalnaZmienna1, lokalnaZmienna2); to po powrocie z tej metody zmienne lokalnaZmienna1 i lokalnaZmienna2 będą na 100% miały taką samą zawartość jak przed wywołaniem (czyli będą miały tą samą wartość prymitywną lub ten sam adres co wcześniej).

"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 3x, ostatnio: Wibowit

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.