Java

[Java] Call by Value (vs) Call by Reference

블로그 주인장 2024. 4. 26.

Call by Value vs Call by Reference

프로그래밍 언어들의 메서드 매개변수 호출 방식에는 여러가지가 있으며

호출 방식은 언어마다 다르게 되어 있습니다.

 

Call by Value 형식과 Call by Reference 형식에 대해 알아보고 전달하는 방식에 대해 알아보겠습니다.

 

 

Call by Value

Call by Value 는 값을 전달하는 방식을 뜻하며 다르게 말하면 값만 전달하는 방식이라고 볼 수 있습니다.

 

만약 메서드 A에서 B로 int 변수를 전달한다고 가정한다면

넘겨받은 B에서는 어떤 행동을 하던지 변수에는 변함이 없습니다.

 

public static void init() {
    int a = 10;
    int b = 20;
    System.out.println("Before Method : " + "a = " + a + " b = " + b);
    swap(a, b);
    System.out.println("After Method : " + "a = " + a + " b = " + b);
}

public static void swap(int a, int b) {
    a = 20;
    b = 10;
    System.out.println("swap : " + "a = " + a + " b = " + b);
}

 

위의 예시를 보면 init 메서드와 change 메서드가 존재할 때

init() 에서는 a = 10, b = 20 값을 넘겨주고, swap() 에서는 해당 값을 swap 하게 됩니다.

 

 

위의 출력 값을 확인해보면 init () 함수에서는 a = 10, b = 20 넘겨주고

swap()에서는 해당 값을 치환했는데 여전히 init() 메서드에서는 값이 동일합니다.

 

이를 바로 Call by Value 방식이라고 볼 수 있고 Java가 해당 형식을 사용한다고 볼 수 있습니다.

 

 

Call by Reference

위의 테스트를 바꿔서 새롭게 선언한 클래스를 가지고 테스트를 진행해보겠습니다.

static class Point {
    int x;
    int y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public static void init() {
    Point point = new Point(10, 20);
    System.out.println("Before Method : " + "x = " + point.x + " y = " + point.y);
    swap(point);
    System.out.println("After Method : " + "x = " + point.x + " y = " + point.y);
}

public static void swap(Point point) {
    point.x = 20;
    point.y = 10;
    System.out.println("swap : " + "x = " + point.x + " y = " + point.y);
}

 

위의 코드를 출력해보면 이전 결과와 다르게 출력된 것을 확인할 수 있습니다.

 

 

Reference Type 동작 원리

기존 상식으로 보면 자바에서는 Call by Value 방식을 사용하는 것을 알 수 있습니다.

그렇다면 int a, b를 전달할 상황과 Point를 전달할 때는 어떤 차이가 있었는지 확인해보겠습니다.\

 

자바에서는 Call by Value 형식을 수행할 때,

값을 넘겨받은 메서드에서 값을 복사하여 새로운 지역변수에 저장하게 됩니다.

 

이 때 swap() 메서드에서는 init()의 변수를 사용하는 것이 아닌,

자신이 새롭게 생성한 지역 변수에 init() 의 변수 이름과 변수 값을 복사하여 사용하게 됩니다.

 

이를 통해 swap에서 값을 변경해도 기존 init 메서드에는 영향을 끼칠 수 없습니다.

즉, A와 B는 이름만 같을 뿐 다른 주소를 가지는 별개의 객체이기 때문입니다.

 

 

그럼 Point에서는 왜 변경된 결과가 나왔는지 알아보겠습니다.

 

위의 이미지처럼 Heap Memory 영역에 생성된 객체의 주소값을 참조하기 때문입니다.

 

즉, init 메서드에서 swap 메서드로 넘겨준 것은 Point의 주소값이고

init 메서드가 가지고 있는 주소값과 동일한 주소값을 가진 객체의 상태를 수정하면

동일한 주소를 참조하기 때문에 변경됩니다.

 

마무리

call by value는 인자로 받은 값을 복사하여 처리를 하는 기법입니다.

call by Reference는 인자로 받은 값의 주소를 참조하여 값에 직접적인 영향을 주는 기법으로 정리할 수 있습니다.

 

 

 

 

본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다.

 
 
반응형

'Java' 카테고리의 다른 글

[Java] HashMap 정렬하기  (0) 2024.04.14
[Java] List -> Map 으로 변환하는 이유  (0) 2024.04.05
[Java] Arrays 배열 복사 - copyOf, copyOfRange  (0) 2024.03.22

댓글