[Java] Call by value 와 Call by reference

박상군·2022년 5월 17일
1

Java

목록 보기
4/4
post-thumbnail

Call은 Retrofit에서 많이 봤는데..

Call by value 와 Call by reference 자바가 아닌 다른 언어에서도 쓰이는 개념으로 다들 들어는 보고 뭔지는 알고 있지만 막상 설명해 보라고 하면 헷갈리는.. 나만 그런가..

아무튼 이 둘은 비슷하면서 비슷하지 않은 개념인데 메모리 구조를 아신다면 이해가 빠르실겁니다.
우리가 구현하는 함수들이 호출 될때는 메모리 공간 안에서 임시의 공간이 생성됩니다.
함수가 종료되면 해당 공간은 사라지게 되고요
이때 함수 호출시 변수를 어떤 방식으로 전달하느냐에 따라 Call by valueCall by reference 로 나뉩니다.

📌Java의 경우엔 함수에 전달되는 인자의 데이터 타입에 따라서 위의 호출 방식이 달라집니다.

  • 기본 자료형 : Call by value 로 동작 (int, String, short, long, float, double, char, boolean)
  • 참조 자료형 : Call by reference 로 동작 (Array, Class의 Instance)

1. Call by value (값에 의한 호출)

  • 함수 호출시 전달되는 변수의 값을 복사하여 인자로 전달
  • 전달된 인자는 함수내에서 지역적으로 사용하는 변수
  • 장점: 복사하여 처리하기 때문에 안전하다. 원래의 값이 보존
  • 단점: 복사를 하기 때문에 메모리가 사용량이 늘어남

예제

public class ValueTest {
    public static void changeValue(int x, int y) {
        int tmp = x;
        x = y;
        y = tmp;
    }
 
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
 
        System.out.println("a: "+ a +" b:" + b);
        changeValue(a, b);
        System.out.println("a: "+ a +" b:" + b);
    }
}

>> a: 1 b: 2
>> a: 1 b: 2

출력한 값을 확인하면 바뀌지 않았다.
이런식으로 Call by value는 값을 복사하여 인자로 넘기기 때문에 a와 b의 값을 changeValue() 함수안에서만 바뀌기 때문에 값을 바꾸더라도 실제 a와 b의 값는 바뀌지 않습니다.

2. Call by reference (참조에 의한 호출)

  • 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달 (해당 변수를 가르킴)
  • 함수 안에서 인자의 값이 변경되면, 함수 호출시에 있던 변수들도 값이 바뀜
  • 장점 : 복사하지 않고 직접 참조를 하기 때문에 빠름
  • 단점 : 직접 참조를 하기 때문에 원래 값이 영향을 받음

예제

public class ReferenceTest {
    int value;

    public ReferenceTest(int value) {
        this.value = value;
    }
    
    public static void changeValue(ReferenceTest x, ReferenceTest y) {
        int tmp = x.value;
        x.value = y.value;
        y.value = tmp;
    }

    public static void main(String[] args) {
        ReferenceTest a = new ReferenceTest(1);
        ReferenceTest b = new ReferenceTest(2);
        
        System.out.println("a: "+ a.value +" b:" + b.value);
        changeValue(a, b);
        System.out.println("a: "+ a.value +" b:" + b.value);
    }
}

위의 코드에서 보면 ReferenceTest라는 객체를 만들어서 참조 변수인 x와 y를 넘기므로 Call by reference입니다.
☝ 그러나 이때 changeValue(a, b);에서 a와 b의 객체 주소값을 직접 넘기는 게 아닌 a객체와 b객체를 가르키는 또다른 주소값을 넘깁니다.


마무리

평소에 알고 있던 개념이지만 막상 설명해 보라고 하면 헷갈리는 것이라 정리하며 개념을 다시 익힌 것 같다!!👍
메모리 공부는 더 하는걸로..

0개의 댓글