[부트캠프] TIL - Java의 Call by Value, Call by Reference
오늘의 알고리즘 코드카타를 보다가 문뜩 떠오른 내용이다,
어떤 문제였는지 모르지만, 생각나는 대로 풀이를 하다가 바로 이 부분에 있어서 동작의 차이가 발생하여
의도한 바와 다른 결과가 나온 적이 있었다.
마침 오늘 떠오른 김에 이 부분에 대한 기록을 남긴다.
자바의 데이터 타입에는 두 가지가 있다.
1. 기본형 데이터 - 원시 타입으로 boolean, short, int, long, float, double 같은 기본 자료형 데이터 타입들이 해당된다.
2. 참조형 데이터 - 클래스. 배열 등 사실상 기본형 데이터 타입에 해당하지 않는 모든 것이라고 볼 수 있다.
이것들이 어떤 차이가 있는가 하면 바로 함수의 파라미터로 전달될 때 동작방식이 다르다는것.
public class main{
public static void main(String[] args){
int a = 1:
int[] arr = {1,2,3};
callByValue(a);
System.out.println(a);
callByReference(arr);
System.out.println(arr[0]);
//결과는
//1
//2 가 출력된다,
}
public static void callByValue(int n){
n = n +1;
}
public static void callByReference(int[] n_arr){
n_arr[0] = n_arr[0] + 1;
}
}
정말 이부분이 헷갈렸었다, 하지만 이전에 정리했던 Stack 영역과 Heap 영역의 내용과 연관이 있다고 한다.
이번에는 그 부분에 대해서 100% 숙지했기 때문에 이것 역시 숙지하고 넘어가보자.
원시 타입 변수는 저장된 값을 Stack 영역에 저장한다.
참조 타입 변수는 저장된 값을 Heap 영역에 저장한다, 그리고 Stack 영역에는 Heap 영역에 저장한 자신의 값이 있는 곳의 주소값!!!을 저장한다.
그리고 또한 영역개념이란게 존재하는데, 좀 딥한 영역인것 같아서 간단하게 내가 이해한 식으로
나만의 언어로 정리하자면, 생명주기 란 개념으로 a변수는 main 함수의 괄호 안에서 남아 있는것이다.
그리고 마찬가지로 callByValue()가 호출되면 n 변수에 a의 값을 전달하였는데 이것은 callByValue 함수의 영역이
Stack영역에 생성되고, 그 안에 n이라는 변수에 a의 값을 복사하여 저장하는것이다.
**a와 n 둘 다 Stack 영역에 자신이 담은 값 자체를 저장하지만, 둘이 소속된 영역이 다른 것이다, 즉 아예 다른 존재라고 볼 수 있다. 또한 중요한게, 만약 callByValue 함수의 실행이 종료가 되었다. 리턴이 있던 없던 코드의 실행이 끝나서 다시 main 함수의 실행 흐름으로 돌아왔을 때, n의 생명주기는 끝나고 Stack 영역에서 n의 값이 지워지는것.
언어능력이 많이 부족하여 깔끔하게 정리할 순 없었지만 이정도면 충분히 숙지했다고 생각 할 수 있을 것 같다.
이와는 다르게, arr 배열의 경우는 오히려 더 쉽다! 뭐 영역이니 생명주기니 필요없이
아까 n이 a의 Stack 영역의 값을 복사해서 전달받았다고 하지않았는가? arr의 Stack 영역에는 무엇이 있는가?
바로 Heap 영역의 주소이다! 따라서, 같은 주소값을 가지게 되므로
callByReference()함수에서는 같은 주소값의 Heap 영역을 참조하여 그곳의 값을 직접 바꿔
함수의 실행이 끝나서 Stack 영역의 n_arr의 영역? 데이터? 가 지워지더라도 이미 Heap 영역의 같은 주소를 참조하고있던 arr의 값 역시도 바뀐 상태 그대로 유지되는것.
이곳저곳 많이 뒤져보고 찾아보면서 이번에는 100퍼센트 숙지했다고 자신할 수 있게 되었다.