[Java] Call by value? Call by reference?

j-yong98·2026년 2월 6일

Java

목록 보기
2/7
post-thumbnail

프로그래밍에서는 함수로 인자를 전달할 때 크게 ‘Call by value’와 ‘Call by reference’ 방식으로 나뉜다.

전달 방식은 변수의 값이 어떻게 복사되거나 참조 공유 되는지를 결정한다. Java에서는 객체와 기본 타입의 전달 방식이 혼동되는 경우가 많아, 실제로 어떤 방식으로 인자가 전달되는지 정확히 이해하는 것이 중요하다.

Call by value와 Call by reference의 개념을 비교하고, Java에서의 동작 방식을 중심으로 살펴보자.

Call by value

Call by value는 함수 호출 시 전달되는 값을 복사하여 넘기는 방식이다. 함수 내부에서는 복사된 값을 사용하기 때문에 원본 데이터가 직접 변경되지 않아 안전성이 높다는 특징이 있다. 다만 전달되는 데이터의 크기가 클 경우, 복사 비용이 발생하여 성능에 영향을 줄 수 있다.

Call by reference

Call by reference는 함수 호출 시 값 자체가 아닌 메모리 주소(참조)를 전달하는 방식이다. 함수 내부에서 동일한 데이터를 공유하기 때문에 복사 비용 없이 효율적으로 처리할 수 있다. 하지만 원본 데이터가 직접 변경될 수 있어 의도하지 않은 에러가 발생할 가능성이 있다.

자바는?

자바는 기본적으로 Call by value 방식으로 동작한다. 다만 객체를 전달할 때는 객체 자체가 아니라 객체를 가리키는 참조값(reference value) 이 복사되어 전달되기 때문에, 마치 Call by reference처럼 보이는 경우가 있다.

아래 예제를 통해 이를 확인할 수 있다.

public static void main(String[] args) {
    Person p = new Person();
    p.age = 10;
    System.out.println(p); // 5
    testAge(p);
    System.out.println(p); // 50
    testNull(p);
    System.out.println(p); // 50
}

private static void testAge(Person p) {
    p.age = 50;
}

private static void testNull(Person p) {
    p = null;
}

static class Person {
    int age;

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
}

testAge 메서드에서는 전달받은 Person 객체의 age 값을 50으로 변경한다. 이때 함수로 전달되는 것은 객체 자체가 아니라 객체를 가리키는 참조값의 복사본이다.

복사된 참조값 역시 동일한 객체를 가리키기 때문에, 해당 객체의 내부 상태(age 필드)를 변경하면 원본 객체에도 그대로 반영된다. 따라서 testAge 호출 이후 출력 결과에서 age 값이 50으로 변경된 것을 확인할 수 있다.

반면 testNull 메서드에서는 매개변수 p에 null을 할당하고 있다. 하지만 이는 복사된 참조값 변수 자체를 변경하는 것일 뿐, 원본 변수에는 영향을 주지 않는다.

즉, 메서드 내부에서 p = null을 수행해도 원래의 변수는 여전히 동일한 객체를 참조하고 있으므로 이후 출력에서도 정상적으로 객체가 출력된다.

만약 자바가 Call by reference 방식이었다면, 함수 내부에서 참조 자체를 변경했을 때 호출한 쪽의 변수도 함께 변경되어 null이 출력되어야 했을 것이다. 하지만 실제 결과는 그렇지 않다.

0개의 댓글