자바는 call by value 일까 call by reference 일까

StarSeeker·2022년 12월 20일
0

결론만 말한다면 자바는 'call by value'이다.

많은 사람들이 헷갈려 하는 부분이 객체를 파라미터로 넘길때 인 것같다.

Dog my dog;

에서 dog는 객체 그자체를 의미하는 게 아니라 Dog의 참조값을 가르키는 포인터역할이라고 생각하면 이해하기가 쉽다.

예를 들자면,

public class Main {

     public static void main(String[] args) {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }

     public static void changeReference(Foo a) {
          Foo b = new Foo("b");
          a = b;
     }

     public static void modifyReference(Foo c) {
          c.setAttribute("c");
     }

}

위의 예제에서 사람들은 f가 b의 객체가 가르키고 있는 new Foo("b")로 바뀌엇다고 생각하기 쉽다.
하지만 여기에서 parameter로 들어온 Foo a 는 f의 참조값이 복사되어서 정의된다.
따라서 처음에는 변수 a, f는 같은 객체를 가르키고 있다.
그후 a가 선언된 b로 교체되면 b가 가르키고 있는 참조값이 그대로 넘어가게되어 기존 f와 같은 객체를 가리키고 있는 변수가 b가 가르키는 객체로 바뀌었을 뿐이다.
따라서 f는 변하지 않는다.

그림으로 보면 이해하기 쉽다.

처음 f의 참조값이 복사되어 a에 할당된다. 이때 f와 a는 같은 객체를 가르키게 된다.
b가 선언되어 새로운 객체가 생성된다.


그후 a=b를 선언하면, a가 가르키는 객체값이 바뀐다. (f가 아니라!!)
따라서 원본 f는 변하지 않는다.

오해하는 이유

많은 사람들이 오해하는 이유는 객체의 원본 attribute 값은 잘 바뀌기 때문이다.
그 이유는 참조값을 넘겼기 때문에 잘 바뀌는게 당연하다!

마치 C언어의 포인터처럼 변수는 그 참조값을 가르키는 화살표 처럼 작동하고 그 변수를 아무리 바꿔봣자 가르키는 객체만 바뀔뿐 원본 f 가 가르키는 객체의 값을 바꿀수는 없다.

profile
춤추듯 개발하고 싶은 사람

0개의 댓글