만자의 개발일지

[Java] Call by value 와 Call by reference 본문

Java/Java

[Java] Call by value 와 Call by reference

박만자 2021. 6. 16. 21:28

자바의 인자 전달 방식에 대해 다뤄보도록하겠습니다.

인자 전달 방식에는 크게 두 가지가 있습니다.

바로 Call-by-valueCall-by-reference 입니다.

그렇다면 자바는 Call-by-value 일까요 Call-by-reference 일까요?

일단 자바는 항상 Call-by-value 방식입니다.

그 이유에 대해 한번 천천히 알아봅시다.😀

 

일단 들어가기 앞서 Call-by-value Call-by-reference가 뭔지, 두 방식의 차이점은 무엇인지 부터 짚고 넘어가봅시다.

 

Call-by-value

일단 Call-by-value 는 해석하면 "값에 의한 호출" 이라고 할 수 있습니다.

"값에 의한 호출"이 무슨 말일까요?

"값에 의한 호출"이란 인자값을 전달해줄때 값을 복사하여 전달해줍니다.

Call-by-value 는 오로지 값만 복사하여 전달해주기 떄문에 해당 객체 혹은 변수에 대한 직접적인 핸들링은

하지 못합니다.

그렇기 때문에 a,b의 값이 바뀐다 한들 x,y의 값이 바뀌지 않는 이유도 이 때문입니다.

 

 

Call-by-reference

그렇다면 Call-by-reference 는 어떨까요?

Call-by-reference 는 해석하면 "참조에 의한 호출" 이라고 할 수 있습니다.

"참조에 의한 호출"이란 인자로 값이 아닌 메모리주소를 넘겨줌으로써 해당 매게변수는 주소를 참조함으로써 객체에 대한 직접적인 핸들링 권한을 가집니다.

객체에대한 직접적인 핸들링 권한을 가지기 떄문에 a,b 가 변경되면 x,y도 같이 변경되게 됩니다.

 

 

자 이제 Call-by-value Call-by-reference 에 대해 간략히 짚어 봤으니

자바에서의 인자 전달 방식을 알아보도록 합시다.

 

아까 자바는 Call-by-value 방식으로 인자를 전달 한다고 했죠?

하지만 자바에서의 Call-by-value 는 아까 우리가 배웠던 Call-by-value 와 조금 다릅니다.

 

자바의 인자 전달 방식에서 중요한 부분은 **메모리 주소를 복사하여 전달**한다는 것입니다.

말로 이해하려니까 어려우시죠?

 

예시 코드를 통해 쉽게 이해해 봅시다.

class Test{
	
	int value;
	
	Test(int value) {
		this.value = value;
	}
	
}

public class Main {
	
	public static void main(String[] args) {
		Test a = new Test(10);
		Test b = new Test(20);
	}
	
	static void changeByValue(Test a1, Test b1) {
		a1.value = 100;
		a1 = b1;
	}
}

필드로 정수형 변수 value를 하나 선언한다음 생성자로 그 값을 받는 Test클래스를 선언해 주었습니다.

main 메서드를 살펴보시죠. 각각의 10,20을 생성자 인자 값으로 받는 Test a,b를 선언해 주었습니다.

그렇다면 현재 자바의 메모리 상태는 이렇겠죠?

이렇게 선언한 변수를 chageByValue() 라는 메서드의 인자로 전달해주었습니다.

changeByValue() 메서드에서는 a1의 필드변수인 value의 값을 100으로 초기화해주고 a1 을 b1으로 초기화 해줍니다.

함수를 호출하였기 때문에 Call Stack 메모리 영역에 메서드가 올라가고 각각의 new Test(10),new Test(20) 가 가르키고 있는 메모리주소를 복사하여 전달할 것입니다.

changeByValue() 메서드의 인자로 전달하게되면 보시다시피 a 와 a1, b 와 b1이 같은 메모리 주소를 참조하고있는 것을 보실 수 있을껍니다. 

static void changeByValue(Test a1, Test b1) {
  a1.value = 100;
  a1 = b1;
}

chageByValue() 메서드를 다시 한 번 살펴보면 a1 이 가르키고있는 객체의 필드변수인 value를 100으로 바꿔주고 a1을 b1으로 초기화 해줍니다.

a1은 a의 메모리 주소를 복사하여 참조하고 있기 때문에 같은 객체를 가르키고있습니다.

그렇기 떄문에 a1이 참조하고있는 인스턴스에 대한 핸들링 권한을 가지고 있습니다.

그래서 a1 value값을 100으로 바꾼다면 a의 value값도 100으로 바뀌게 될 것입니다.

 

자 그럼 a1을 b1으로 초기화 해봅시다.

a1은 a의 메모리주소를 복사하여 참조한다고했죠? 그렇기 때문에 a1을 b1으로 초기화하여도 a에 직접적인 영향을 끼치진 않습니다. a1 은 이제 b1을 참조하고 있지만 a는 그대로인 것을 보실 수 있을 겁니다.

이것이 자바의 인자 전달 방식입니다.

 

 

자 그럼 정리해봅시다.

자바에서 의미하는 value는 객체에 대한 주소값 또는 원시 타입의 값이고,자바는 인자 전달 방식으로 항상 Call-by-value를 사용합니다. 자바에서의 Call-by-value는 쉽게 말해 객체를 핸들링할 수 있는 권한을 가진다고 생각하시면 쉽습니다.

글로 이해하기보다는 코드를 쳐보고 머리속으로 그림을 그리면서 이해하시면 더욱 더 도움이 되실겁니다.😀

 

https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value/12429953#12429953

 

Is Java "pass-by-reference" or "pass-by-value"?

I always thought Java uses pass-by-reference. However, I've seen a couple of blog posts (for example, this blog) that claim that it isn't (the blog post says that Java uses pass-by-value). I don't ...

stackoverflow.com

더 자세한 내용이 알고 싶으시다면 위 사이트를 참고해주세요.

'Java > Java' 카테고리의 다른 글

[Java] new 연산자란  (0) 2021.06.21
[Java] 리터럴(literal)이란?  (0) 2021.06.18
[Java] Java에서 MySQL 접속하기  (0) 2021.05.02
[Java] Anonymous Class(익명클래스) 란?  (0) 2021.03.02
[Java] String matches  (0) 2021.02.26
Comments