27 Passing Variables into Methods

Merhaba Arkadaslar,
Java da pass-by value ve pass-by-rerefence kavramlarini bol miktarda duymusuzdur. Bir metodun, taniminda aldigi degiskenler(parametreler) hem primitive/ilkel hem de referans tipte olabilir.

Primitive/ilkel tipte degiskenler icin bir degiskeni diger degiskene atamak ; icerigini/content yani bit pattern/bit yapisini bir degiskenden diger bir degiskene kopyalamak anlamina gelmektedir. Obje referans degiskenlerini icin de bu durum gecerlidir ! Referans degiskenin icerigi/content bir bit pattern/yapi/ornek dir. Yani a referans degiskenini b referans degiskenine atamak , a ‘nin bit pattern’ini , b’nin bit pattern’ine kopyalamak anlamina gelmektedir.

Obje Referans Degiskeni ile Metot Cagirma 
Bir metoda , bir obje referans degiskeni gonderdigimizde , objenin kendisini degil o objenin referans degiskenini gonderiyoruz. Hatirlayacagimiz gibi bir referans degisken de bit holder/tutucudur.Yani tuttugu bu bitler ilgili objeye nasil ulasacaginin bilgisini tasir.

Aslinda, ilgili objenin referans degiskenini gonderiyoruz desek de aslinda referans degiskeninin bir kopyasini gonderiyoruz ! Yani degiskenin bit pattern/kalibinin kopyasini alip gondermekteyiz. Boylece 2 tane identical/ozdes referans degiskeni olacaktir. Bu iki referans degisken de Heap’teki ayni objeye referansta bulunacaktir. Burada yeni bir obje olusmadigini belirtmek gerekir .

Test.java

package passbyreference;

class Numbers {
	int num1;
	int num2;

	public Numbers(int num1, int num2) {
		super();
		this.num1 = num1;
		this.num2 = num2;
	}

	protected void addValue(Numbers n) {
		System.out.println("main method");
		n.num1=n.num1+10;
		n.num2=n.num2+20;

		System.out.println("numb1:" + n.num1);
		System.out.println("numb2:" + n.num2);
	}
}

public class Test {

	public static void main(String[] args) {

		Numbers number = new Numbers(10,20);
		System.out.println("Before Method Call");
		System.out.println("numb1:" + number.num1);
		System.out.println("numb2:" + number.num2);

		number.addValue(number);

		System.out.println("After Method Call");
		System.out.println("numb1:" + number.num1);
		System.out.println("numb2:" + number.num2);
	}

}

Ornegimizi inceleyecek olursak , Numbers sinifimizda 2 tane int turunde instance degisken tanimladik ve Test sinifimizda bir referans degisken ve obje olusturduk. “number” referans degiskenimizi addValue metoduna gonderdik, burada num1 ve num2 alanlarini degistirdik (20 ve 40 yaptik) sonrasinda ise main metodunda “number” referans degiskenimizin tuttugu objenin num1 ve num2 alanlarini yazmak istedik ve biraz once degistirdigimiz 20 ve 40 degerleri olarak degistigini gorduk. Cunku ortada 1 obje var ve 2 referans degisken de bu objeye referansta bulunmaktadir boylece ikisi de degisiklik yapabilmektedir.

Aslinda Java ister primitive/ilkel ister obje referans tipinde degisken olsun pass-by-value kuralina gore calismaktadir. Pass-by-value demek Pass-by-variable-value demektir aslinda pass-by-copy-of-the variable demektir !

Ornegin int turunde bir degiskenin degeri 5 olsun, aslinda 5 degerini ifade eden bitlerin kopyasini metoda gondermekteyiz. Eger obje referans turunde bir degisken gonderiyorsak bu referans degiskeni ifade eden bitlerin kopyasini metoda gondermekteyiz.
(pass-by-copy-of-the-bits-in-the-variable)

Bir diger detay noktayi daha inceleyelim ; yukaridaki ornekte degiskenin degerini degistirdik fakat cagrilan metot icerisinde orijinal referans degiskenin baska bir objeye referansta bulunmasini ya da null olmasini saglayamayiz.

Test2.java

package passbyreference;

class Foo {
	String name = "volkan";

	void bar() {
		Foo f = new Foo();
		System.out.println(f.name);
		doStuff(f);
		System.out.println(f.name);
	}

	void doStuff(Foo g) {
		System.out.println(g.name);
		g.name = "ozturk";
		System.out.println(g.name);
		g = new Foo();
		g = null;

	}

}

public class Test2 {
	public static void main(String[] args) {

		Foo f = new Foo();
		f.bar();

	}
	/*
	 * volkan
	 * volkan
	 * ozturk
	 * ozturk
	 */

}

g degiskeninin yeni bir objeye referans olmasini saglamak (g = new Foo(); ) , f degiskeninin ayni objeye referans olmasini saglamaz !  Benzer sekilde g degiskenini null yapmak , yani hic bir objeye referansta bulunma demek f degiskenini etkilemez.
Bunun nedeni doStuff metodu referans degiskeninin kopyasina sahip , aslina degil ! doStuff metodu Foo objesine giden yolu bilmekte fakat f referans degiskenine giden yolun bilgsini bilmemektedir. Bu nedenle doStuff metodu objenin durumunu/state degistirebilirken , f degiskeninin farkli bir objeye referans olmasini saglayamaz.

Primitive/Ilkel Tipte Degisken Ile Metot Cagirma
Bir primitive/ilkel tipte degiskeni metoda gonderdigimizde, herkesin bildigi anladam pass-by-value kurali islemektedir yani pass-by-copy-of-the-bits-in-the-variable.

Ornegimizi inceleyecek olursak , num1 degiskenimize 10 degerini atiyoruz ve modify metodunu cagirip degiskenin degerini degistiriyoruz (15) fakat main metoduna tekrar geri geldigimizde ve num1 degerimizi yazdirdigimizda aslinda degiskenimizin degismedigini gorururuz.

Test3.java

public class Test3 {
	public static void main(String[] args) {

		int num1=10;
		System.out.println(num1);
		modify(num1);
		System.out.println(num1);
	}
	static void modify(int num) {
		num = num+5;
		System.out.println(num);
	}
	/*
	10
	15
	10
	*/
}

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*
*