09009

[Java] Call By Value, Call By Reference 본문

Back-End/JAVA
[Java] Call By Value, Call By Reference
09009

Call By Value

main 메서드 안에 작성된 데이터가 기본형인 경우 메서드를 호출하였을 때 값을 전달한 것이지 주소를 전달한 것이 아니다.

출력 결과를 확인하였을 때 class B1에 있는 m1 메서드 안에서의 결과와 main 메서드 안에서의 결과가 다르다는 사실을 확인할 수 있다.

→  즉, main 메서드 안에서 작성된 데이터가 기본형인 경우, 따로 정의한 메소드 안에서 바뀐 결과는 원래 데이터에 영향을 주지 않는다.

class B1 {
	void m1(int x, int y) {  // 전달한 것은 x = 10, y = 20 
		x += 7; y += 5;
		System.out.println("m1 x = " + x);
		System.out.println("m1 y = " + y);
	}
}

public class CallByValue1 {
	public static void main(String[] args) {
		B1 a1 = new B1();
		int x = 10, y = 20; // 데이터가 기본형인 경우
		a1.m1(x, y); // 값 10, 20을 전달한 것이지 변수 x, y를 전달한 것이 아니다
		System.out.println("main x = " + x);
		System.out.println("main y = " + y);
	}
}

 

💻 출력 결과

 

m1 x = 17
m1 y = 25
main x = 10
main y = 20

 

아래와 같이 두 변수의 값을 서로 바꾸는 소스 코드에서도 마찬가지이다. 

class B2 {
	void m1(int a, int b) { // 전달한 것은 x = 10, y = 20
//	    CallByValue: 메소드 안에서 바뀐 결과는 원래 데이터에 영향을 주지 않는다.
//		a와 b값을 서로 교환해서 출력
		int temp;
		temp = a;
		a = b;
		b = temp;
		System.out.println("m1 x = " + a);
		System.out.println("m1 y = " + b);
	}
}

public class CallByValue2 {
	public static void main(String[] args) {
		B2 a1 = new B2();
		int x = 10, y = 20; 
		a1.m1(x,y);
		System.out.println("main x = " + x);
		System.out.println("main y = " + y);
	}
}

 

💻 출력 결과

m1 x = 20
m1 y = 10
main x = 10
main y = 20

 

main 메서드에서 두 기본형 변수를 정의하고 class B2에 작성된 m1 메서드를 호출하였을 때, m1 메서드 안에서의 결과는 바뀌었지만, main 메서드에서 출력된 결과는 원래 데이터에서 변하지 않았다는 것을 알 수 있다.

 

 

 

 

Call By Reference

위의 소스코드에서 데이터가 기본형인 경우에는 메서드에서 바뀐 결과는 원본 데이터에서 바뀌지 않았다는 것을 알 수 있었다.

하지만 참조형 데이터의 경우에는 어떨까? 참조형 데이터는 값을 전달하는 기본형과 달리 주소를 전달하기 때문에 메서드 안에서 결과가 바뀌면 원본 데이터도 바뀌게 된다.

 

✍ 입력

class C1 { 
	void m1(int[] num) {
		num[0] = 77; num[1] = 100; // 전달된 주소를 찾아가서 값을 변경
		for(int i = 0; i < num.length; i++) {
			System.out.println("m1 num["+i+"] = " + num[i]);
		}
	}
}

public class CallByRef1 {
	public static void main(String[] args) {
		C1 c1 = new C1();
		int[] num = {12, 34, 66}; // 배열은 참조형, 참조형 데이터는 주소를 전달한다.
		c1.m1(num);				 // call by reference: 참조형은 주소를 전달하므로 메서드에서 바뀌면 원본 데이터도 바뀐다.
		for(int i = 0; i < num.length; i++) {
			System.out.println("main num["+i+"] = " + num[i]);
		}
	}
}

 

 

💻 출력 결과

m1 num[0] = 77
m1 num[1] = 100
m1 num[2] = 66
main num[0] = 77
main num[1] = 100
main num[2] = 66

출력 결과에서 보이는 바와 같이 배열과 같은 참조형 데이터의 경우, m1 메서드 안에서 결과가 바뀐 것이 main 메서드에서도 적용되었다는 것을 알 수 있다.

 

객체의 경우에도 마찬가지이다.

 

✍ 입력

class C2 {
	int x, y;
	public void m1(C2 c) {
//		x와 y를 서로 교환하고 c.x, c.y를 출력
		int temp = c.x;
		c.x = c.y;
		c.y = temp;
		System.out.println("m1 x = " + c.x);
		System.out.println("m1 y = " + c.y);
	}
}
public class CallByRef2 {
	public static void main(String[] args) {
//		C2 c를 생성하여 c.x = 10, c.y = 20을 대입하고 m1() 메서드에 c를 전달
//		c.x와 c.y를 출력
		C2 c = new C2();
		c.x = 10; c.y = 20; // 객체도 참조변수이므로 주소를 전달, 참조변수는 원본데이터가 바뀌면 같이 바뀐다.
		c.m1(c);
		System.out.println("main x = " + c.x);
		System.out.println("main y = " + c.y);
	}
}

 

💻 출력 결과

m1 x = 20
m1 y = 10
main x = 20
main y = 10

 

객체도 참조형이기 때문에 주소를 전달하므로 메서드 안에서 결과가 바뀌면 원본 데이터도 바뀌게 된다.