본문 바로가기
Baeldung번역&공부/Java-basic

Pass-By-Value메커니즘 설명(Pass-By-Value as a Parameter Passing Mechanism in Java)

by ms727 2025. 2. 8.

원본 글: https://www.baeldung.com/java-pass-by-value-or-pass-by-reference

함수에 인자를 전달할 때 "passing-by-value", "passing-by-reference"라는 대표적으로 이야기하는 2가지 방식이 있습니다.
프로그래밍 언어마다 두 개념을 다른 방식으로 사용합니다. Java에서는 모든 것들을 Pass-by-Value형태로 인자를 전달합니다.

 

이 글에서는 Java가 어떻게 다양한 유형의 타입들을 함수에 전달하는지 학습합니다.

1. Pass-by-Value vs Pass-by-Reference

함수에 인자를 전달하는 방식에는 value, refrence, result, value-result, name 등의 방식으로 전달할 수 있는데 대부분 value, reference 2가지 방식 중 하나를 택해서 이를 전달합니다.

1.1 Pass-by-value

해당 방식은 함수를 호출하는쪽에서 인자를 전달할 때 그 값을 복사해서 전달합니다. 그렇기에 인자를 받은쪽에서 값을 수정해도 원본 값은 변하지 않습니다.

1.2 Pass-by-Reference

이 방식은 함수를 호출하는쪽에서 인자를 전달할 때 그 값 자체를 보냅니다. 따라서 함수안에서 그 값을 수정하면 원본 값도 수정됩니다.

2. Parameter Passing in Java

모든 프로그래밍 언어의 기본 개념은 value(값)과 references(참조)를 가지고 있습니다.
Java에서는 원시 타입의 변수는 실제 값을 저장하고, 참조타입 변수는 객체의 주소를 가리키는 참조 값을 저장합니다.
두 값 모두 스택 메모리 영역에 저장됩니다.

자바에서 인자를 전달할때 원시 타입의 변수나 참조타입 변수 모두 passed-by-value으로 전달합니다.
원시 타입 변수는 그 값이 스택 메모리에 복사되어 함수로 전달됩니다. 값이 직접 전달되기에 함수 내에 값이 변경되어도 원본 값이 변경되지 않습니다. 참조 타입(예: 객체)의 경우, 참조값(reference) 이 스택 메모리에 복사되어 함수로 전달됩니다. 참조값이란 객체가 실제로 저장되어 있는 힙 메모리의 주소값을 말합니다. 호출된 메서드 내에서 객체의 속성이나 상태를 변경하면, 그 변경 사항은 원본 객체에도 영향을 미칩니다. 다만, 참조값이 복사되어 전달되므로, 객체 자체를 교체하는 등의 작업은 원본 객체에 영향을 미치지 않습니다.

2.1 Passing Primitive Types

위에서 원시 타입 변수는 값이 복사되어 함수에게 넘어간다했습니다. 이 값은 함수 실행기간에만 유효합니다. 즉, 함수에서 Return을 진행하면 이 복사값은 스택에서도 사라지고 폐기됩니다.
다음은 그 예제입니다.

    @Test
    public void 원시타입은_함수에서수정해도_원본값은변하지_않는다() {
        int x = 1;
        int y = 2;

        Assertions.assertEquals(x,1);
        Assertions.assertEquals(y,2);

        modify(x,y);

        Assertions.assertEquals(x,1);
        Assertions.assertEquals(y,2);
    }

    public static void modify(int x1, int y1) {
        x1 = 5;
        y1= 10;
    }
  • 변수 x, y는 모두 원시타입으로 선언되었습니다. 그리고 이 값은 스택 메모리에 저장됩니다.
  • modify()함수에서는 이 값들을 복사해서 스택 메모리 내 다른 공간에 저장합니다.
  • 이 복사된 값은 수정되어도 원본 값이 수정되지 않습니다.

 

출처: https://www.baeldung.com/java-pass-by-value-or-pass-by-reference

2.2 Passing Object References

Java의 모든 객체는 Heap 메모리에 저장됩니다. 이렇게 저장되는 객체들을 참조 변수라는 참조됩니다.

참조 변수는 스택영역에 저장되고 이를 가리키고 있는 객체 자체는 힙 메모리에 저장됩니다.

 

따라서 객체를 인자로 넘길때에는 참조 변수를 복사해서 힙 메모리에 있는 객체 자체를 가리키는 새로운 포인터를 생성합니다.  때문에 함수내에서 해당 객체를 수정하면 원본 객체도 같이 수정됩니다. 그러나 전달된 참조 변수에 새 객체를 할당하면 원본 객체에 영향을 미치지 않습니다.

 

    @Test
    public void 참조타입은_함수에서수정하면_원본값이변한다() {
        Foo a = new Foo(1);
        Foo b = new Foo(1);

        Assertions.assertEquals(a.num,1);
        Assertions.assertEquals(b.num,1);

        modify(a,b);

        Assertions.assertEquals(a.num,2);
        Assertions.assertEquals(b.num,1);
    }

    public static void modify(Foo a1, Foo b1) {
        a1.num++;

        b1 = new Foo(1);
        b1.num++;
    }
    
    
public class Foo {
    public int num;

    public Foo(int num) {
        this.num = num;
    }
}

 

modify()함수에 Foo라는 오브젝트를 넘겼습니다. 초기에는 힙 메모리 영역이 다음과 같이 되어있었습니다.

값을 넘긴 이후 스택 메모리에는 새로운 참조 변수가 생겼을 겁니다.

그런데 modify()함수 내에서 b1변수는 새로운 객체를 할당하였습니다. 그렇기에 메모리 구조는 다음과 같이 변경되었을 겁니다. 그래서 값이 수정되어도 원본값은 변하지 않았습니다.

 

 

3. 결론

 

이 글에서는 원시타입과 참조타입이 함수와 메모리관계에서 어떻게 동작하는지 확인하였습니다.