티스토리 뷰

 

프로그래밍에서 함수에 값을 전달하는 방식에는 Call by Value(값에 의한 호출)Call by Reference(참조에 의한 호출)가 있습니다. Java는 항상 Call by Value 방식을 사용합니다. 하지만 객체를 전달할 때는 참조가 전달되는 것처럼 보이기 때문에 혼동이 생길 수 있습니다. 이 글에서는 Java에서 Call by Value가 어떻게 동작하는지, 그리고 객체를 전달할 때 발생하는 개념적 차이를 코드와 함께 살펴보겠습니다.

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

Call by Value는 메서드에 인수를 전달할 때, 원본 값을 복사하여 전달하는 방식입니다. 즉, 메서드 내부에서 값이 변경되더라도 원본 변수에는 영향을 미치지 않습니다.

기본형 데이터 타입에서 Call by Value 예제

public class main {
    public static void main(String[] args) {
        int a = 1; // primitive 타입 변수 int

        // 변수 자체를 보냄 (call by value)
        callMethod(a);
        System.out.println(a); // 1 : 값 변화가 없음

    }

    static void callMethod(int a) {
        a += 100;
    }
}

실행 결과

위 코드에서 callMethod(a)를 호출했지만, 메서드 내부에서 num을 변경해도 a의 값은 변하지 않습니다. 이는 a의 값이 num에 복사되었기 때문입니다.


2. 객체(Object)에서 Call by Value의 동작

자바에서 객체를 메서드에 전달할 때, 참조 값(reference value, 즉 주소값)이 복사되어 전달됩니다. 하지만 이는 Call by Reference가 아니라, 참조형 변수의 Call by Value입니다.

객체 전달 예제 (참조값이 복사됨)

public class Main {
    public static void main(String[] args) {
        // 객체 생성
        MyObject obj = new MyObject();
        obj.value = 1;

        // 객체 자체를 보냄 (Call by Value)
        callMethod(obj);
        System.out.println(obj.value); // 101 : 값 변화가 있음
    }

    static void callMethod(MyObject obj) {
        // 객체의 내부 값 변경
        obj.value += 100;
    }
}

class MyObject {
    int value;
}

실행 결과

MyObject라는 객체를 사용하여 callMethod 메서드에 객체를 전달하고, 그 객체의 value 속성을 변경합니다. Java에서 객체는 참조 타입이므로, obj의 참조를 전달하게 되어, 메서드 내에서 객체의 상태가 변경될 수 있습니다. 이로 인해 obj.value 값이 101로 변경됩니다.

즉, 객체를 전달할 때는 참조가 전달되므로, 객체의 값을 변경할 수 있게 되어 "Call by Reference"와 비슷한 동작을 합니다.

하지만 참조 자체를 변경하면 원본에는 영향을 미치지 않습니다.

객체의 참조 변경 예제

public class Main {
    public static void main(String[] args) {
        // 객체 생성
        MyObject obj = new MyObject();
        obj.value = 1;

        // 객체 참조를 변경하려는 시도
        System.out.println("Before callMethod: " + obj.value); // 1
        changeReference(obj);

        // 객체의 참조가 변경되지 않음
        System.out.println("After callMethod: " + obj.value); // 여전히 1
    }

    static void changeReference(MyObject obj) {
        // 새로운 객체로 참조를 변경
        obj = new MyObject();
        obj.value = 100; // 변경된 객체의 값은 100
    }
}

class MyObject {
    int value;
}

실행 결과

 

changeReference 메서드에서 obj 참조가 새로운 MyObject 객체로 변경되지만, 이 변경은 메서드 내에서만 발생합니다. 즉, 메서드 외부의 obj 참조는 영향을 받지 않습니다.메서드 외부에서 obj.value를 출력하면, obj는 여전히 원본 객체를 참조하고 있으므로 값은 1로 그대로 유지됩니다.

 


3. Java에서 Call by Reference는 존재하지 않는다

C++ 같은 언어에서는 Call by Reference를 통해 변수의 실제 메모리 주소를 직접 참조할 수 있지만, Java에서는 모든 값이 복사되어 전달됩니다. 객체를 전달할 때도 객체 자체가 복사되는 것이 아니라 참조 값(메모리 주소)이 복사되므로, 객체 내부의 값은 수정할 수 있지만 참조 자체는 변경되지 않습니다.

 

  • 기본형 데이터는 값이 복사되어 전달되므로 원본이 변경되지 않음 → Call by Value
  • 객체는 참조 값이 복사되어 전달되므로 객체 내부 값은 변경 가능 → Call by Value of Reference
  • 메서드 내부에서 객체 자체를 새로운 객체로 변경해도 원본에는 영향을 미치지 않음
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함