• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Java pass by value

Object Storage Arubacloud
0 głosów
687 wizyt
pytanie zadane 20 lutego 2019 w Java przez periedynek Obywatel (1,320 p.)

Cześć. Mam pytanie odnośnie tego, że Java jest przekzywana przez wartość.

Mam dwa przzykłady z SO:

public class Main{
     public static void main(String[] args){
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }
     public static void changeReference(Foo a){
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c){
          c.setAttribute("c");
     }
}

Tutaj wszystko rozumiem w changeReference tworzymy nową referencję, dlatego nie działamy na tym samym adresie.

Ten obrazek to pokazuje:

I mam drugi kod:

private void foo(Object bar) {
    bar = null;
}

public static void main(String[] args) {
    String baz = "Hah!";
    foo(baz);
    System.out.println(baz);
}

W metodzie foo nie tworzymy żadnych nowych instancji, dlatego dlaczego nie wypiszę się null tylko Hah?

Czy to nie jest taka sama metoda jak modifyReference z 1 przykładu?

1
komentarz 20 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
W drugim przykladzie bar jest zmienna referencyjna ktora wskazuje na ten sam adres co baz. Ale gdy nullujesz wartosc bar to poprostu tracisz informacje o adresie tego obiektu, a nie zmieniasz jego wartosc.

3 odpowiedzi

+3 głosów
odpowiedź 20 lutego 2019 przez RafalS VIP (122,820 p.)
        String baz = "Hah!";
        Object bar = baz;
        bar = null;
        System.out.println(baz);

Robisz coś takiego.

komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
No tak, tutaj jasno widać, że są to dwa różne obiekty. Ale są to dwa różne obiekty, z tego względu, że jedno to jest kopia drugiego.

Nie rozumiem dalej, dlaczego w 1 zmieniamy,a w drugim nie (w 1 oczywiście rozumiem dladczego tak się dzieje i jest to logiczne).

Jeżeli miałbys rozpisać 1 przykład w taki sam sposób jak rozpisałeś to jakby on wyglądał?
komentarz 21 lutego 2019 przez RafalS VIP (122,820 p.)
        Foo f = new Foo("f");
        //changeReference(f); :
        Foo a = f;
        Foo b = new Foo("b");
        a = b;
        //modifyReference(f); :
        Foo c = f;
        c.setAttribute("c");

 

+1 głos
odpowiedź 20 lutego 2019 przez Asertywny Mądrala (5,430 p.)
edycja 20 lutego 2019 przez Asertywny
Przekazujesz obiekt typu string (by value!) do funkcji foo.

Funkcja foo przypisuje do swojej kopii (by value!) tej referencji inną wartość.

Funkcja foo dokonała zmian tylko w swojej kopii tej referencji (Jeszcze raz - przekazano argument BY VALUE, dlatego działa na kopii), a następnie wychodzi ze swojego bloku i ta zmiana nie jest nigdzie zapisana.
1
komentarz 20 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
Wydaje mi sie ze sie mylisz. W Javie wartosci przekazywane sa by Value, ale nie oznacza to ze robiona jest kopia obiektu. Przekazywana jest wartosc referencji do obiektu f. Metoda ustawia wartosc referencji na null nie zmieniajac wartosci obiektu.
1
komentarz 20 lutego 2019 przez Asertywny Mądrala (5,430 p.)
Pewnie, że tak. Pisząc "kopię obiektu" miałem na myśli kopię referencji...
Dzięki za zauważenie
komentarz 20 lutego 2019 przez periedynek Obywatel (1,320 p.)

@Asertywny, W takim razie co by się musiało stać by się ta wartość zmieniła? Bo w 1 przykładzie też działam na kopii referencji...

komentarz 21 lutego 2019 przez Asertywny Mądrala (5,430 p.)
Wyobraź sobie obiekt jako balonik gdzieś w powietrzu, a referencję, jako nitkę do niego połączoną. Do jednego obiektu może iść wiele nitek.

Gdy przekazujesz "obiekt" do funkcji, tworzysz nową nitkę i dajesz ją tej funkcji.

Funkcja może zmieniać obiekt, wysyłając zmiany po tej nitce.

Pass by value oznacza tyle, że tworzysz KOPIĘ referencji, a nie przekazujesz jej bezpośrednio.
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
No dobrze, ale no to nie jest odpowiedź na to co pytałem:D

W 1 przykładzie nie tworzę nowego obiektu, tylko tworzę kopie i ta kopia ma tę samą nitkę do tego samego obiektu.

W 2 przykładzie też nie tworze nowego obiektu, tylko tworzę kopie przesłanego obiektu i ta kopia ma tę samą nitkę do tego samego obiektu.

Dla mnie te 2 przykłądy są niemalże identyczne, dlatego nie potrafię tego zrozumieć.
komentarz 21 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
Osobiscie nie rozumiem twojej watpliwosci. W tak podanych przykladach nie mozliwe jest abys zmienil wartosc zmiennej poza funkcja.

Jedynie mozesz zmienic wartosc atrybutu w obiekcie. Akurat obiekty string sa niezmienne "immutable", wiec string po przeslaniu do funkcji zawsze bedzie mial ten sam stan. Inne obiekty takie jak np AtomicString moga miec zmienialny stan
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
Ale to wciaż nie jest to o co pytam przecież :D

Pytam o to, dlaczego mimo tego, że w 1 jak i 2 przykładzie nie tworzymy nowego obiektu, to w 1 przykładzie zmieniamy coś w obiekcie, a w drugim nie zmieniamy.
komentarz 21 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
Nie rozumiem pytania. Ani w pierwszym ani w drugim przykladzie z pytania nie zmieniasz obiektu.

Dopiero metoda modifyReference cokolwiek robi z obiektem i zmienia jego stan. Ale wydaje mi sie ze nie o to pytasz
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
No tak, chodzi mi o modifYReference.

Może źle zintepretowałeś albo ja wystarzzajaco jasno nie napisałem.

Nie chdozi mi o jakaś podmianę obiektu na inny, tylko chodzi mi o właśnie zmienienie jakiegos atrybutu w obiekcie.

W 1 przykładize w modifyReference zmieniamy w tym obiekcie, nie tworząc nowego obiektu. W 2 przykłądzie nie zmieniamy nic w tym obiekcie, nie tworząc nowego obiektu.
komentarz 21 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
Rozumiem, troche sie nie dogadalismy.

Masz tu jakas watpliwosc, co do tego?
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
No tak. Cały czas te same.

W 1 przykładzie w modifyReference nie tworzymy nowego obiektu i zmieniamy stan przesłanego obiektu. Wynika to z obrazka, ponieważ kopia wskazuje na to samo.

 

W 2 przykładzie mam wg mnie identyczną sytuacje. Mamy kopie, wskazuje ona na to samo.

Kopie ustawiamy na null i stan nam się nie zmienia w oryginalnym obiekcie. Dlaczego?
komentarz 21 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
W 2 przypadku nie modyfikujesz obiektu tylko zerujesz referencje. To nie jest ten sam przypadek
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
To jest nielogicznie przecież :/ W tym i w tym coś zmieniam. W 2 przypadku jeżeli były jakieś dane to są one teraz wszystkie nullami.
komentarz 21 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
No nie. Nie traktuj referencji do obiektu jako obiekt. Referencja to jest adres. Jak pozbedziesz sie adresu to nie oznacza ze obiekt przestaje istniec.
1
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)

Może jeszcze inaczej. 

Czy patrząc na ten obrazek, który zamieściłem w pytaniu i patrząc na 2 przykład, to czy obrazek w 2 przykładzie by wyglądał tak:

1. Przed linijką z metody. 2 Po linijce z bar=null

1
komentarz 21 lutego 2019 przez Mateusz51 Nałogowiec (28,180 p.)
Tak
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)

W takim razie, dzieki wielkieheart

0 głosów
odpowiedź 21 lutego 2019 przez Arkadiusz Fajdek Dyskutant (9,450 p.)
Hej! Java zawsze jest "pass by value", można by się tutaj naprawdę rozpisać na ten temat, jednak bardzo dobrym postem który wyjaśnia ten temat jest wpis na niezawodnym stack overflow;) https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
komentarz 21 lutego 2019 przez periedynek Obywatel (1,320 p.)
wlasnie stamtad sa te przyklady

Podobne pytania

0 głosów
1 odpowiedź 825 wizyt
0 głosów
1 odpowiedź 446 wizyt
0 głosów
1 odpowiedź 125 wizyt

92,584 zapytań

141,434 odpowiedzi

319,671 komentarzy

61,968 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...