[Java] Java의 Call by Value

청포도봉봉이·2024년 8월 11일
1

java

목록 보기
20/20
post-thumbnail

많은 개발자들이 Java의 매개변수 전달 방식에 대해 혼란을 겪곤 합니다. "Java는 Call By Value인가, Call By Reference인가?"라는 질문에 대한 답변은 간단하면서도 복잡합니다. 이번 포스트에서는 Java의 매개변수 전달 방식을 자세히 살펴보고, 흔히 발생하는 오해를 풀어보겠습니다.

Java는 항상 Call By Value

결론부터 말하자면, Java는 항상 Call By Value 방식을 사용합니다. 하지만 이 말이 의미하는 바를 정확히 이해하는 것이 중요합니다.

기본 타입(Primitive Types)의 경우

기본 타입(int, float, double 등)의 경우, 값 자체의 복사본이 메서드에 전달됩니다. 따라서 메서드 내에서 매개변수 값을 변경해도 호출한 곳의 원본 값은 변하지 않습니다.

예제 코드:

public class PrimitiveExample {
    public static void main(String[] args) {
        int number = 10;
        System.out.println("Before method call: " + number);  // 출력: 10
        changeNumber(number);
        System.out.println("After method call: " + number);   // 출력: 10 (변하지 않음)
    }

    public static void changeNumber(int x) {
        x = 20;  // 이 변경은 호출한 곳의 number에 영향을 주지 않음
    }
}

객체 참조(Object References)의 경우

객체의 경우, 객체에 대한 참조값(메모리 주소)의 복사본이 전달됩니다. 이 때문에 많은 개발자들이 Call By Reference라고 오해하곤 합니다. 하지만 실제로는 참조값 자체가 Call By Value로 전달되는 것입니다.

  1. 객체의 내용 변경:
    메서드 내에서 참조를 통해 객체의 내용을 변경하면 원본 객체도 변경됩니다.

  2. 참조 자체의 변경:
    메서드 내에서 참조 자체를 변경(새로운 객체를 할당)해도 호출한 곳의 원본 참조는 변하지 않습니다.

예제 코드:

public class ObjectExample {
    public static void main(String[] args) {
        // 객체 내용 변경 예시
        StringBuilder sb = new StringBuilder("Hello");
        System.out.println("Before method call: " + sb);  // 출력: Hello
        changeStringBuilder(sb);
        System.out.println("After method call: " + sb);   // 출력: Hello World

        // 객체 참조 변경 예시
        Person person = new Person("John");
        System.out.println("Before method call: " + person.getName());  // 출력: John
        changePerson(person);
        System.out.println("After method call: " + person.getName());   // 출력: John (변하지 않음)
    }

    public static void changeStringBuilder(StringBuilder s) {
        s.append(" World");  // 이 변경은 호출한 곳의 sb 객체에 반영됨
    }

    public static void changePerson(Person p) {
        p = new Person("Jane");  // 이 변경은 호출한 곳의 person 참조에 영향을 주지 않음
    }
}

class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

결론

Java에서 모든 매개변수 전달은 Call By Value 방식으로 이루어집니다. 기본 타입의 경우 값 자체가, 객체의 경우 참조값이 복사되어 전달됩니다. 이를 이해하면 메서드 호출 시 발생할 수 있는 side effect를 더 잘 예측하고 관리할 수 있습니다.

이러한 특성을 잘 이해하고 활용하면, 더 안전하고 예측 가능한 코드를 작성할 수 있습니다. 또한 이는 Java의 메모리 관리와 객체 지향 프로그래밍의 기본 원리를 이해하는 데에도 중요한 개념입니다.

profile
서버 백엔드 개발자

0개의 댓글