Przekazywanie parametru przez wartość i referencję

2016-12-02 15:03

Rejestracja: 7 lat temu

Ostatnio: 3 tygodnie temu

0

Cześć

Korzystam z poradnika 4prorammers dotyczącego "Przekazywanie parametru przez wartość i referencję" w odniesieniu do Javy.
Odnosząc się do tego zdania "Standardowo parametry funkcji (pod tym pojęciem rozumiem również metody w klasach) są przekazywane przez wartość. Czyli funkcja operuje na kopii zmiennej która została do niej przekazana." z wyżej wymienionego artykułu napisałem taki kod:

public class Testy4 
{

    public static void main(String[] args) 
    {

        int x = -1;
        foo(x);
        System.out.println(x);

    }
    static void foo(int x)
    {
        x = 34;
        System.out.println(x);
    }

} 

I wszystko się zgadza w odniesieniu do wyżej przytoczonego stwierdzenia - metoda

foo

bazuje na kopii zmiennej, pierwszy print to 34 a drugi to -1.
Ale już patrząc na ten kod tak nie jest:

 Public class MyClass
{
    public static void main(String[] args)
    {
        StringBuilder sb = new StringBuilder("Hello");
        System.out.println(sb);
        StringBuilder sb2 = sb;
        sb2.append(" World!");
        System.out.println(sb);

    }
}

Dlaczego tutaj metoda

append 

użyta na zmiennej sb2

sprawia, że zmienna referencyjna <code class="java">sb 

przyjmuje tutaj zainicjowaną wartość " World!"?

Czy chodzi o to, że przekazanie wartości przez wartość sprawia, że w metodzie działamy na kopii, a przekazanie przez referencje sprawia, że odnosimy się do bazowego obiektu?

Pozostało 580 znaków

2016-12-02 15:05

Rejestracja: 8 lat temu

Ostatnio: 2 dni temu

2

tutaj masz swietnie wytlumaczone dlaczego ;)

http://stackoverflow.com/ques[...]by-reference-or-pass-by-value

edytowany 1x, ostatnio: fasadin, 2016-12-02 15:12

Pozostało 580 znaków

ŁF
2016-12-02 15:16
ŁF
Moderator

Rejestracja: 17 lat temu

Ostatnio: 44 sekundy temu

2

W drugim przypadku nie ma żadnej mowy o parametrach. sb2 = sb = "Hello", czyli sb2 jest referencją do zawartości sb. Nie zachodzi żadne automagiczne kopiowanie obiektu sb. W takiej sytuacji wywołanie append na sb2 jest tożsame z wywołaniem tego na sb (oba wskazują na ten sam obiekt), więc dostajesz "Hello World!" w drugiej linijce.
Jeśli zrobiłbyś to samo przez metody i parametry, to efekt byłby identyczny, bo w parametrze leci tylko kopia zmiennej (czyli niejako kopiowany jest wskaźnik na obiekt), a nie całego obiektu.


Pozostało 580 znaków

2016-12-02 15:17

Rejestracja: 5 lat temu

Ostatnio: 2 miesiące temu

1

Model w Javie jest najbliższy przekazywaniu przez wskaźnik w C++. Referencja w Javie jest jak wskaźnik w C++ i ona jest przekazywana przez wartość. Wyjątkiem są typu proste jak np. int, gdzie semantyka jest taka jak zwykłe przekazywanie przez wartość w C++.

Pozostało 580 znaków

2016-12-02 16:38

Rejestracja: 7 lat temu

Ostatnio: 3 tygodnie temu

0

A czy taki kod jest poprawny?

public class MyClass
{

    public static void main(String[] args)
    {       
        Integer x = new Integer(10);
        foo(x);
        System.out.println(x);

    }

    static void foo(Integer x)
    {
        x = 20;
        System.out.println(x);
    }
} 

Pytam w odniesieniu do tego, że mam w głowie stwierdzenie "Typy proste odpowiadają przekazywaniu przez wartość, a typy obiektowe to przekazywanie przez referencje". A z tego co zrobiłem wynika, że przekazałem typ obiektowy przez referencje. Coś źle rozumiem?

Pozostało 580 znaków

2016-12-02 16:49
Moderator

Rejestracja: 11 lat temu

Ostatnio: 1 minuta temu

0

Skoro się kompiluje i wykonuje, to jest poprawny.
Moim zdaniem, wszystkie typy są przekazywane przez wartość, tylko co innego jest wartością dla typów prostych, a co innego dla obiektowych.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2016-12-02 17:18

Rejestracja: 7 lat temu

Ostatnio: 3 tygodnie temu

0

Czegoś dalej nie rozumiem:

public class MyClass
{

    public static void main(String[] args)
    {
        //Przykład 1
        StringBuilder sb = new StringBuilder("Hello");
        System.out.println(sb);
        StringBuilder sb2 = sb;
        sb2.append(" World!");
        System.out.println(sb);

        //Przykład 2
        Integer zmienna = new Integer(1);
        System.out.println(zmienna);
        Integer zmienna2 = zmienna;
        zmienna2++;
        System.out.println(zmienna2);
        System.out.println(zmienna);
}} 

W przykładzie pierwszym po użyciu metody append zmieni się wartość obiektu na który wskazują zmienne

sb

i sb2

. A w przykładzie drugim po inkrementacji tylko zmienna <code class="java">zmienn2

zwiększa swoją wartość. Jak to jest, że w pierwszym przykładzie dwie zmienne wskazują na ten sam obiekt i użycie metody append zmienia wartość danego obiektu, a w przypadku drugim już to tak nie działa?

edytowany 1x, ostatnio: rubesom, 2016-12-02 17:19

Pozostało 580 znaków

2016-12-02 18:25
Moderator

Rejestracja: 11 lat temu

Ostatnio: 1 minuta temu

0

Przypuszczam, że wytłumaczenie jest takie: operacja zmienna2++ wymaga "rozpakowania" - konwersji Integer na int. Po tej operacji następuje (zmienna2 jest typu Integer) "zapakowanie" - konwersja int na Integer. Bardzo prawdpodobne, że podczas tej drugiej konwersji wykorzystywany jest operator new.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0