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

Przekazywanie obiektów jako parametrów funkcji

Object Storage Arubacloud
0 głosów
840 wizyt
pytanie zadane 6 sierpnia 2016 w Java przez itcloud Gaduła (3,380 p.)

Dlaczego gdy przekazujemy obiekty do metody, to przy np. zamianie ich miedzy sobą po wyjściu z metody te obiekty są nienaruszone (czyli podobnie jak ze zmiennymi - przekazywana do funkcji była ich kopia, tzn. kopia referencji?)

A jak jest ta zamiana dokonywana nie w metodzie tylko w ciele main() to zamiana ma miejsce ? Poniżej mój testowy kod.

import java.util.*;

public class Test {
	
	int a;
	String napis;

	//konstruktor
	public Test(){
		a = 1;
		napis = "Napis";
	}
	
	//konstruktor nr2 z argumentami
	public Test(int a, String n){
		this.a = a;
		this.napis = n;
	}

	
	public int getA(){
		return this.a;
	}
	

	public String getNapis(){
		return this.napis;
	}
	
	//#1 metody nie moga modyfikowac parametrow liczbowych
	public static void changeZmienna(int x){
		
		//proba zmiany zmiennej o nazwie zmienna (ale sie nie uda, bo do x jest kopiowana wartosc, która ginie po wyjściu z funkcji)
		x = x+1;

	}

	//#2 metody moga modyfikowac stan obiektu - jesli jest utworzony obiekt
	public void setA(int x){
		
		//proba zmiany skladowej a - uda sie, praca na obiekcie
		this.a = x;

	}
	
	public static void zamienObiekty(Test a, Test b){
		Test t = a;
		a=b;
		b=t;
		System.out.println("Przed opuszczeniem zamienObiekty: t1="+a.getNapis()+", t2="+b.getNapis());
	}

	public static void main(String[] args){

		int zmienna = 666;
		System.out.println("Test #1: przed - "+zmienna);
		changeZmienna(zmienna);
		System.out.println("Test #1: po - "+zmienna);
		
		Test t1 = new Test();
		System.out.println("Test #2: przed - "+t1.getA());
		t1.setA(4);
		System.out.println("Test #2: po - "+t1.getA());
		
		Test t2 = new Test(2,"Napis2");
		
		Test tmp = t1;
		t1 = t2; //a dlaczego TUTAJ DZIALA - zmienna referencyjna t1 wskazuje teraz na obszar wczesniej wskazywany przez t2
		t2 = tmp; //i na odwrot
		
		System.out.println(t1.getNapis()); //t1 pokazuje na to co bylo na poczatku w t2
		System.out.println(t2.getNapis()); //i na odwrot -- DLACZEGO TUTAJ NIE DZIALA?

		zamienObiekty(t1,t2);
		System.out.println("Po opuszczeniu zamienObiekty: t1="+t1.getNapis()+", t2="+t2.getNapis());
		
	}
	
}

Tzn. mam na myśli to, że przecież do funkcji przekazuję jakaś zmienna referencyjną, czyli referencje do jakiegoś miejsca w pamięci. Domyślam się, że musiałbym przy wyjściu robić returna i przypisywać do czegoś, żeby tego co było wykonywane w metodzie nie utracić. No a w main() również kopiuję referencję (wskazywanie na jakiś obszar pamięci, na jakąś wartość) i przypisuję ją do innej zmiennej referencyjnej. I tutaj ta podmiana działa.

W c++ przy przekazywaniu referencji do funkcji wszystko było ok w tym sensie, że operowało się właśnie na danej wartości (a nie na jej kopii).
 

2 odpowiedzi

0 głosów
odpowiedź 6 sierpnia 2016 przez obl Maniak (51,280 p.)

Czyli nie rozumiesz podstaw. Gdy przekazujesz funkcji jako parametr obiekt klasy lub jakąś zmienną typu prostego to tworzona jest kopia tego obiektu lub zmiennej. I działasz na kopii tego obiektu bądź zmiennej a nie na tym samym obiekcie. Dlatego też np. metoda:

public static void changeZmienna(int x)

Nie zadziała zadziała tak jak ci się to wymarzyło, ale wystarczy użyć referencji:

public static void changeZmienna(int &x)

I zmiana będzie działała.

komentarz 6 sierpnia 2016 przez itcloud Gaduła (3,380 p.)
Heh, chyba nie doczytałeś co dokładnie pisałem. Co do c++ jest to dla mnie jasne. Pytanie dotyczy javy.
komentarz 6 sierpnia 2016 przez obl Maniak (51,280 p.)

W takim razie przepraszam, mój błąd.

Z tego co wygooglowałem nie można przekazywać int-a przez referencje w Javi-e http://stackoverflow.com/questions/3326112/java-best-way-to-pass-int-by-reference

komentarz 6 sierpnia 2016 przez itcloud Gaduła (3,380 p.)
W tym przykładzie składowa jest publiczna tak w ogóle. To chyba nie do końca to o co mi chodziło, ale dzięki.
0 głosów
odpowiedź 6 sierpnia 2016 przez Przybysz_4444 Gaduła (3,200 p.)
System.out.println(t2.getNapis()); //i na odwrot -- DLACZEGO TUTAJ NIE DZIALA?

 

 t2 wskazuje już tutaj inną  zawartość niż po nadaniu "Napis2", ponieważ przekazałeś jej zwartość tmp, która zaś = t1, czyli posiada stan przed nadaniem "Napis2". Czyż chodzi o to?

 

A jak jest ta zamiana dokonywana nie w metodzie tylko w ciele main() to zamiana ma miejsce ?

Tak, main()  także jest metodą, w której także można dokonywać zmian. 

komentarz 6 sierpnia 2016 przez itcloud Gaduła (3,380 p.)

Tak, wiem że w tym fragmencie, który jest bezpośrednio w main():

		Test tmp = t1;
		t1 = t2; //a dlaczego TUTAJ DZIALA
		t2 = tmp;

działa to tak, jakbym się spodziewał. Tzn. składowe które wcześniej były w obiekcie t1 są teraz w t2 i odwrotnie.

Ale prosiłbym o wytłumaczenie, czemu dzieje się inaczej przy przekazywaniu dwóch obiektów t1, t2 do metody i przy zamianie wewnątrz tej metody. Jako argumenty też są przekazywane zmienne referencyjne wskazujące dany obiekt, więc nie do końca to rozumiem w odniesieniu do referencji stosowanej w c++.

Z drugiej strony przy przekazywaniu zmiennej referencyjnej która nie jest obiektem (typ prosty) działa to tak, że zmiana odbywa się lokalnie w danej metodzie a po wyjściu z niej nic się tak naprawdę nie zmienia.

Z obiektami jest podobnie jak z typami prostymi. Po prostu jak to jest:tylko przy przekazywaniu parametrów do funkcji są to zawsze kopie wewnątrz tej funkcji w JAVA?

Podobne pytania

0 głosów
2 odpowiedzi 147 wizyt
pytanie zadane 9 marca 2018 w PHP przez Bartess Gaduła (3,630 p.)
0 głosów
1 odpowiedź 257 wizyt
pytanie zadane 17 stycznia 2017 w C i C++ przez BeSSeSSt Obywatel (1,190 p.)
0 głosów
4 odpowiedzi 2,676 wizyt
pytanie zadane 19 lipca 2016 w JavaScript przez Madar Obywatel (1,560 p.)

92,584 zapytań

141,434 odpowiedzi

319,669 komentarzy

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

...