article thumbnail image
Published 2022. 7. 14. 20:35

 

메서드에 인수를 전달하는 두가지 모드

Call by value란, 값을 호출하는 것을 의미. 매개변수로 전달받은 값을 복사하여 처리합니다. 즉 전달받은 값을 변경하여도 원본은 변경되지 않는다

Call by reference란 참조에 의한 호출을 의미. 매개변수로 전달받은 값을 직접 참조합니다. 즉 전달받은 값을 변경할 경우 원본도 같이 변경된다

 

그렇다면 자바의 참조형은 Call by reference일까?

 

결론적으로 말하자면 Call by Value이다.

 

자바에서 기본(Primitives) 변수는 실제 값을 저장하는 반면 비기본(Non-Primitives) 변수는 참조하는 객체의 주소를 가르키는 참조변수를 저장한다. 값과 참조 모두 Stack 메모리에 저장된다.

 

자바의 인수는 항상 값으로 전달된다. 메서드를 호출하는 동안 값이든 참조이든 각 인수의 복사본이 Stack 메모리에 생성되어 메서드에 전달된다. 기본형은 단순히 Stack 메모리 내부에 복사된 다음 호출 수신자 메서드에 전달된다. 참조형은 Stack 메모리의 참조는 Heap에 있는 실제 데이터를 가르킨다. 객체를 전달할 때 Stack 메모리의 참조가 복사되고 새 참조가 메서드에 전달된다.

    public void whenModifyingObjects_thenOriginalObjectChanged() {
        Foo a = new Foo(1);
        Foo b = new Foo(1);

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

        modify(a,b);

        Assert.assertEquals(a.num,2);
        Assert.assertEquals(b.num,1);
}
    
    public void modify(Foo a1, Foo b1) {
        a1.num++;

        b1 = new Foo(1);
        b1.num++;
    
}

class Foo {
    public int num;

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

}

 

위의 프로그램은 동일한 값 1을 갖는 a와b를 modify() 메소드에 전달했다. 처음에 이러한 개체는 힙 공간에서 두 개의 개별 개체 위치를 가르킨다

 

이러한 참조 a 및 b가 modify() 메서드에서 전달되면 동일한 이전 객체를 가르키는 참조 a1 및 b1의 복사본이 생성된다.

 

 

modify() 메서드에서 참조 a1을 수정하면 원래 객체가 변경된다. 그러나 참조 b1에 대해 새 객체를 할당했다. 이제 힙 메모리의 새 개체를 가르키고 있다. b1에 대한 모든 변경 사항은 원래 객체의 어떤 것도 반영하지 않는다.

 

 

 

참고

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

'자바' 카테고리의 다른 글

JVM, JDK, JRE, JIT  (0) 2022.07.18
String의 특징  (0) 2022.07.14
equals()와 hashCode()  (0) 2022.07.14
복사했습니다!