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

Przekazywanie / Wywołanie poprzez wartość

Object Storage Arubacloud
0 głosów
492 wizyt
pytanie zadane 1 grudnia 2016 w Java przez rubesom Obywatel (1,690 p.)

Cześć

Mam problem ze zrozumieniem co to znaczy że parametry są przekazywane przez wartość. Może opiszę jak ja to rozumiem i ktoś mnie poprawi...

public class TestClass {
  public static void main(String[] args) {
    String x = "Ola";
 
    System.out.println("x: " + x);
 
    someOp(x);
  
    System.out.println("x: " + x);
  }
  
  public static void someOp(String y) {
    System.out.println("y: " + y);
  
    y = "Ela";
  
    System.out.println("y: " + y);
  }
}

Przypisuje obiekt reprezentujący napis "Ola" do zmiennej x. Wypisuje wartość obiektu wskazanego przez zmienną x. Wywołanie metody someOp(), przekazuje zmienna referencyjną (to jest zmienna referencyjna?) x jako argument wywołania. Wartość tej referencji jest kopiowana do zmiennej lokalnej y. Wyświetlamy wartość zmiennej y po czym przypisujemy do niej inny obiekt (napis "Ela"). Dalej są wyświetlenia... Wynik to:

x: Ola
y: Ola
y: Ela
x: Ola

I teraz to co chcę zrozumieć - w momencie przypisania do zmiennej y inny obiekt (reprezentujący napis "Ela"), zmieniamy też pierwotną referencję na nową (na tą z napisem "Ela")? Ale co w przypadku gdzie przypiszemy zmienną y do zmiennej x... Czy przypisując nową wartość do zmiennej y tym samym zmieniam wartość dla zmiennej x (bo przecież wskazują na ten sam obiekt)?

 

I gdzie w tym wszystkim jest przekazywanie / wywołanie poprzez wartość?

 

Większość materiałów wykorzystałem ze strony LINK

4 odpowiedzi

0 głosów
odpowiedź 2 grudnia 2016 przez Mateusz51 Nałogowiec (28,180 p.)
Referencja jest to jakby wstały wskaźnik na obiekt. Nie można jej zmieniać. Do zmiennej referencyjnej możesz zapisać różne referencie. Ale przypisanie wartości do zmiennej referencyjnej nie zmiennia obiektu który jest już do niej przypisany.

Co do wywołania zauważ że zmienna y w środku funkcji someOp i zmienna x w main to sa dwie różne zmienne. Przekazywanie przez wartosc znaczy tyle ze y wskazuje na dokładnie ten sam obiekt co x( wartość x jest kopiowana do y), ale nadal sa to dwie roznie zmienne. Wiec przypisanie do y jakieś wartosci dotyczy tylko i wylacznie y. x cały czas wskazuje na obiekt pierwotny.

Mam nadzieje że udało mi się to wyjaśnic. Jeśli nie to postaram się to napisać jaśniej
komentarz 2 grudnia 2016 przez Predo Bywalec (2,260 p.)
Trochę zaprzeczasz sam sobie w tym zdaniu :)

"Przekazywanie przez wartosc znaczy tyle ze y wskazuje na dokładnie ten sam obiekt co x( wartość x jest kopiowana do y), ale nadal sa to dwie roznie zmienne."

y nie wskazuje na ten sam obiekt tylko na jego kopię.

W referencjach też nie masz racji. To właśnie poprzez zmienną referencyjną zmieniasz wartość obiektu, na który ona wskazuje. A zmienna referencyjna może wskazywać jednocześnie tylko na jeden obiekt i można zmienić tą referencję na inną. Tzn, że na dany obiekt może wskazywać kilka zmiennych referencyjnych.
komentarz 2 grudnia 2016 przez Mateusz51 Nałogowiec (28,180 p.)
No nie koniecznie.

Wyobraź sobie zmienną referencyjną jako komórke pamieci w kórej to trzymamy adres naszego obiektu czyli jego referencje. Możesz mieć kilka zmiennych referencyjnych czyli kilka komorek do których wpisany jest dokladnei ten sam adres. W tym przypadku x jak i y maja te sama wartosc w znaczeniu wskazuja na ten sam obiekt.

zmienna referencyjna pozwala nam na dostanie sie do obiektu ale zmienniajac zmienna referencyjna czyli nasza komorke pamieci wskazesz na inny obiekt. Wiec w tym sensie zmienna referencyjna moze wskazywac na kilka obiektow. Ale nigdy na dwa jednoczesnie
0 głosów
odpowiedź 2 grudnia 2016 przez Predo Bywalec (2,260 p.)
W tym kodzie nie ma nigdzie przekazywania referencji tylko wartości.

Wywołując funkcję someOp(x) przekazujesz tylko aktualną wartość x jako argument. Nie przekazujesz do funkcji referencji do zmiennej x. Co oznacza że wewnątrz funkcji someOp(String y) użyłeś tylko wartości x, którą przekazałeś do parametru y. Nie operujesz na zmiennej x.

Nie możesz w funkcji someOp(String y) przypisać nic do zmiennej x bo nie ma takiej zmiennej w zasięgu tej funkcji.

Przypisując nową wartość do zmiennej y nie zmieniasz wartości zmiennej x (nie wskazują na ten sam obiekt).

Możesz poczytać co nieco w tym artykule

http://4programmers.net/C/Przekazywanie_parametru_przez_warto%C5%9B%C4%87_i_referencj%C4%99
0 głosów
odpowiedź 2 grudnia 2016 przez rubesom Obywatel (1,690 p.)
edycja 2 grudnia 2016 przez rubesom

Dzisiaj rano wróciłem do tematu i napisałem taki kod:

public class Testy3 
{

	public static void main(String[] args) 
	{
		//Przykład 1
		String tekst1 = "1";
		String tekst2 = tekst1;
		System.out.println(tekst1);
		System.out.println(tekst2);
		tekst2 = "2";
		System.out.println(tekst2);
		System.out.println(tekst1);
		
		//Przykład 2
		String zmienna1 = "test1";
		System.out.println(zmienna1);
		
		metoda(zmienna1);
		
	}
	
	public static void metoda(String zmienna2)
	{
		System.out.println(zmienna2);
		
		zmienna2 = "test2";
		
		System.out.println(zmienna2);
	}

}

Pierwszy przykład.

1.1. W linii 8 zmienna referencyjna tekst2 wskazuje tylko na obiekt który jest reprezentowany przez zmienną tekst1 (który reprezentuje napis "1") czy jest to własna kopia dla zmiennej tekst2?

1.2. W linii 11 tworzy się nowy obiekt i wskazuje na niego zmienna referencyjna tekst2 - dobrze to rozumiem?

Drugi przykład.

2.1. Linia 19 (metoda o nazwie "metoda") - jest to przekazanie wartości obiektu poprzez wartość i jest to kopia którą wskazuje zmienna referencyjna zmienna2, do momentu zainicjowania nowej zmiennej o wartości "test2"? Czy jest to raczej zwykłą referencja i nie ma tu mowy o żadnej kopii?

3. Typy proste odpowiadają przekazywaniu przez wartość, a typy obiektowe to przekazywanie przez referencje?

komentarz 2 grudnia 2016 przez Mateusz51 Nałogowiec (28,180 p.)
1.1 Obie zmienne wskazują na ten sam obiekt.

1.2 Tak

2.1 Dopoki nie przepiszesz wartosci "test2" do zmiennej rowniez obie zmienne wskazuja na ten sam obiekt. W javie nie masz kopiowanych obiektów tylko kopiowane wartosci referencji.

3. Tak
0 głosów
odpowiedź 2 grudnia 2016 przez rubesom Obywatel (1,690 p.)

Czegoś dale 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 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?

komentarz 2 grudnia 2016 przez Mateusz51 Nałogowiec (28,180 p.)
Integer są obiektami niezmiennymi (immutable) tozanczy ze każda operacja na Integerach zwraca nowy Integer.

Czyli zmienna ma w adresie jeden Integer a zmienna2 inny.
komentarz 2 grudnia 2016 przez rubesom Obywatel (1,690 p.)
edycja 2 grudnia 2016 przez rubesom

A jak to się ma do Stringa i metody append w pierwszym przykładzie? Skoro taki kod wykona mi się jak w przykładzie który wyjaśniłeś z Integerem:

public class Testy5 
{

	public static void main(String[] args) 
	{
		
		String a = "ala";
		System.out.println(a);
		String b = a;
		b+="kot";
		System.out.println(b);
		System.out.println(a);
		
		
	}

}

Może StringBuilder ma jakieś specjalne właściwości - inne niż zwykł string?

komentarz 2 grudnia 2016 przez Mateusz51 Nałogowiec (28,180 p.)
String też jest obiektem typu immutable. I np dodawanie w pętli stringów jest bardzo nie wydajne obliczeniowo i pamieciowo bo musisz tworzyć coraz wieksze Stringi I właśnie z tego powodu wymyślono StringBuilder(dla jednowątkowych) i StringBuffer(dla wielowątkowych) czyli obiekty które pozwalaja nam dynamicznie budować Stringi

Podobne pytania

0 głosów
3 odpowiedzi 908 wizyt
pytanie zadane 7 lutego 2017 w C i C++ przez qlucha Obywatel (1,790 p.)
0 głosów
2 odpowiedzi 313 wizyt
pytanie zadane 9 maja 2017 w Java przez rubesom Obywatel (1,690 p.)
0 głosów
1 odpowiedź 379 wizyt
pytanie zadane 1 lipca 2022 w PHP przez Doge Gaduła (3,370 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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!

...