본문 바로가기
Programming/Java

[자바/Java] 메소드4 - call by reference, call by value

by 코딩하는 랄로 2023. 9. 28.
728x90

프로그래밍 언어를 공부할 때 초반에 속을 썩이는 개념 중 하나가 바로 메소드(함수)의 매개변수가 call by value인지 call by reference인지에 대한 것이다.

 

특히 C를 공부할 때 많은 개발 입문자가 좌절을 맛 보는 pointer가 이러한 개념과 밀접하게 연관되어 있기 때문에 pointer에 대해서 이해를 못하면 이 개념 또한 이해하기가 어렵다.

 

하지만 자바에서는 포인터라는 키워드를 사용하지 않으므로 변수 타입에 따라 call by reference, call by value인지 정해지기 때문에 pointer와 같이 사용법이라는 것이 없기 때문에 해당 개념에 대해서만 정확하게 숙지하고 있으면 프로그래밍을 하는데 어려움은 없다.

 

 

 

변수 타입 - 참조냐 아니냐

변수의 타입은 세세하게는 int, double, 배열 등으로 나눌 수 있지만 크게는 primitive type, reference type으로 나눌 수 있다.

 

이 둘의 타입의 차이점은 '참조'이고 여기서 참조란 특정 메모리 공간의 값을 참조함을 의미한다. 자바에서는 primitive type은 참조 타입이 아니기 때문에 해당 변수의 값은 stack 메모리에 저장이 된다.

 

하지만 reference type은 참조 타입으로 heap에서 저장된 메모리의 값을 저장하기 때문에 해당 변수에는 해당 값이 아닌 해당 값을 가지고 있는 메모리의 주소를 값으로 stack 메모리에 저장이 된다.

 

 

위의 그림에서 age는 int형 변수로서 primitive type이기 때문에 32라는 값과 함께 stack메모리에 쌓이지만 name이라는 String 타입의 변수는 reference type으로 heap 메모리에 있는 값을 참조하기 때문에 해당 메모리의 주소값을 가지고 stack 메모리에 쌓이게 된다.

 

이러한 개념을 알고 간다면 call by reference, call by value에 대해 이해하기 훨씬 쉽다.

 

 

 

Call by Value

이름 그대로 값에 의한 호출로서, primitive type을 매개변수로 넘겨줄 때 발생하는 호출이다. 

 

primitive type의 변수는 해당 값을 가지고 stack에 저장되기 때문에 매개변수로서 넘겨줄 때 그 값을 전달할 수 있다. 즉, 해당 매개변수가 똑같은 값을 가지고 초기화되어 stack 메모리에 쌓이게 되는 것이다.

 

예를 들어, 위의 그림에서 age를 넘겨받는 printAge(int)라는 함수가 있다면,

 

public void printAge(int paramAge) {

	System.out.println(paramAge + "살 입니다.");
    
}


int age = 32;
printAge(age);

 

primitive type의 변수 age에 저장된 32가 paramAge에 복사되어 paramAge = 32가 stack 메모리에 쌓이게 되는 것이다. 이 때, 값이 복사가 되는 것이기 때문에 paramAge의 값이 변경된다 해서 기존의 age 값이 변경되지 않는다. 즉, 둘은 독립적인 변수인 것이다.

 

 

 

Call by Reference

이름 그대로 참조에 의한 호출이고, reference type의 변수를 매개변수로서 받을 때 호출되는 방식이다. 

 

위에서 reference type에 대해 알아보았듯이, 해당 타입은 값을 가지고 있는 메모리 공간의 주소를 가지고 있다. 그럴 경우, 매개변수의 값을 넘겨주게 되면 해당 주소가 그대로 복사되어 넘어가게 되는 것이다.

 

그렇기 때문에 매개변수도 해당 주소를 가지게 되므로 두개의 변수가 같은 주소를 참조하게 된다. 즉, 매개변수로 받은 메소드 내에서 해당 주소에 접근하여 값은 변경하게 되므로 기존의 변수로 접근하여도 변경된 값에 접근하게 되는 것이다.

 

이러한 call by reference에 이해가 되지 않는다면 대표적인 reference type인 배열을 매개변수로서 넘겨주어 값을 변경해보면 기존의 배열의 값 또한 변경된 것을 확인 할 수 있을 것이다.

728x90