-
[JAVA] Call by Value 와 Call by reference 란 ?Language/Java 2020. 1. 3. 15:29728x90반응형
C언어를 주로 공부 했던 나는 Call by value 와 Call by reference 에 대해서 call by value 는 값을 넘기는 거고 call by reference 는 포인터를 이용해서 주소를 넘긴다고 알고 있다. 하지만 누군가 나에게 이 개념에 대해서 자세히 묻는다면 나도 깊이있게 이해한 것이 아니기 때문에 위에서 말한 대답정도로만 대답을 할 거 같다. 그래서 먼저 이 개념을 한번 더 정리를 한 후에 JAVA 에서의 Call by value 와 Call by reference 에 대해서 알아보겠다.
https://wayhome25.github.io/cs/2017/04/11/cs-13/
강의노트 12. 함수 호출방식(call-by-value, call-by-reference, call-by-assignment) · 초보몽키의 개발공부로그
패스트캠퍼스 컴퓨터공학 입문 수업을 듣고 중요한 내용을 정리했습니다. 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
wayhome25.github.io
잘 정리를 해놓으셔서 위 블로그는 참고자료 입니다. ( 이해도 잘되고 보기 좋아서 이 부분도 가져 왔습니다! )
공부한 것을 정리하는 TIL 공간입니다!
1. call by value (값에 의한 호출)
- 함수가 호출될 때 메모리 공간 안에서는 임시의 공간이 생성된다. 그리고 함수가 종료되면 해당공간은 사라진다.
- 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
- 복사된 인자는 함수 안에서 지역적으로 사용하는 변수이다.
- JAVA의 경우 함수에 전달되는 인자의 데이터 타입에 따라서 (기본자료형 / 참조자료형 ) 함수 호출 방식이 달라짐
- 기본 자료형 : call by value 로 동작 (int, short, long, float, double, char, boolean)
- 참조 자료형 : call by reference 로 동작 (Array, Class Instance)
2. call by reference (참조에 의한 호출)
- 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (함수 종료시 사라짐)
- call by reference 참조에 의한 호출방식은 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가르킨다.)
- 함수 안에서 인자의 값이 변경되면, 함수 호출시에 있던 변수들도 값이 바뀐다.
이제 Call by value 와 Call by reference 의 차이점을 어느정도 이해했으니 JAVA에서의 두개의 특징을 이해해보자.
내가 이 글을 쓰게 된 이유는 JAVA 공부를 하던 중에 swap 함수를 보았는데 자바는 포인터가 없으니까 그냥 값을 넘겨도 되나? 했지만 되지 않았기 때문에 자세히 공부를 해보고자 글을 쓰게 되었다.
java 에서의 call by value 와 call by reference
자바에서는 진정한 call by reference는 없고 reference 값을 넘기는 것만 있다고 들었는데, 그 말을 이해하지 못하다가 이제서야 이해하게 되었다. 그 이해를 도와준 포스트가 아래 포스트이다. ---------...
dhplanner.blogspot.com
글을 너무 이해하기 좋게 정리를 해주셔서 위의 글을 보면서 공부한 것을 정리하려 합니다.
123456789101112131415161718public class SwapTest {public static void swap(int a, int b) {int tmp = a;a = b;b = tmp;}public static void main(String[] args) {int a = 1;int b = 2;System.out.println(a + " " + b);swap(a, b);System.out.println(a + " " + b);}}다음과 같이 swap 메소드를 만들어서 기본 자료형 a, b 를 인자로 값을 넘겨서 바꿔보려 했다. 하지만 C언어에서는 포인터를 이용하지만 자바에서도.. 그냥 넘기면 안될꺼 같은데? 라는 생각을 했는데 역시나 값은 바뀌지 않는다.
이유는 a, b 는 Call by value 이기 때문이다. (a, b는 기본 자료형의 변수 이기 때문이다)
그래서 위의 블로그의 방식처럼 a,b 를 참조형인 Integer를 이용해서 객체를 생성한 하면 a,b 는 참조 변수가 되므로 Call by reference 가 되겠지? 라고 생각을 해서 되나 안되나 테스트를 해보았다.
123456789101112131415161718public class SwapTest {public static void swap(Integer a, Integer b) {Integer tmp = a;a = b;b = tmp;}public static void main(String[] args) {Integer a = new Integer(1);Integer b = new Integer(2);System.out.println(a.intValue() + " " + b.intValue());swap(a, b);System.out.println(a.intValue() + " " + b.intValue());}}하지만 역시나 바뀌지 않는다.
그 이유는 뭘까? 나도 생각하지 못했지만 검색으로 알게된 사실은 Call by reference는 맞지만 메소드 호출을 할 때 새로운 reference를 만들어 호출하게 만든다는 점이다. (new 연산자를 이용할 때와 boxing을 이용해서 값을 할당할 때의 차이점에 대해서 좀 더 찾아보면 이해가 갈 것이다)
따라서 swap 메소드에서도 해당 객체를 가르키지만 다른 reference 값으로 가르킨다는 것이다.
그러면 JAVA 에서는 Swap 구현을 어떻게 해야 된다는 말이지?
123456789101112131415161718192021public class SwapTest {int value;public SwapTest(int value) {this.value = value;}public static void swap(SwapTest a, SwapTest b) {int temp = a.value;a.value = b.value;b.value = temp;}public static void main(String[] args) {SwapTest a = new SwapTest(1);SwapTest b = new SwapTest(2);System.out.println(a.value + " " + b.value);swap(a, b);System.out.println(a.value + " " + b.value);}}이 코드에 대해서 설명하자면 아까 위에서 말했던 것처럼 객체를 만들어서 참조 변수인 a, b를 넘기면 Call by reference 는 맞다. 하지만 같은 객체를 가르키는 새로운 reference 값이 생긴다고 했다. 그래서 그 새로운 참조변수 값으로 swap 함수에서 값을 바꿔놓는 것이다.
따라서 가장 중요하게 알아놔야 될 것은
JAVA에서 Call by reference는 해당 객체의 주소값을 직접 넘기는 게 아닌 객체를 보는 또 다른 주소값을 만들어서 넘기다는 사실을 꼭 기억하자.
Call by reference와 Call by Value의 차이를 더 깊게 이해하기 위해서는 "메모리 구조"에 대한 많은 이해가 필요하다고 생각한다.
반응형'Language > Java' 카테고리의 다른 글
[Java] Iterable 과 Iterator 이란? (1) 2020.01.18 [JAVA] next(), nextLine() 의 차이 (4) 2020.01.16 [JAVA] Array.sort 와 Collections.sort 의 차이 (0) 2020.01.13 [JAVA] ArrayList와 LinkedList의 차이 (6) 2020.01.12 [JAVA] 다중 상속(multiple inheritance) 이란? (0) 2020.01.02