이숭간 공부기록

[Java] 자바는 Call by Value일까 Call by Reference일까? 본문

공부공부/Java

[Java] 자바는 Call by Value일까 Call by Reference일까?

이숭간 2021. 8. 2. 22:18
728x90

우선 엄연하게 말한다면 자바의 동작방식은 Call by Value이다. 이는 주소(레퍼런스)를 하나의 값으로 보기 때문이다.

자세히 알아보자

 

Call by Value(값에 의한 호출)

  • 함수가 호출될 때, 메모리공간에서 함수를 위한 별도의 임시공간이 생성된다. (메모리 스택공간)
  • 함수 호출시 인자로 전달되는 변수의 값(메모리에 저장되어있는)을 복사하여 함수의 인자로 전달한다.
  • 복사된 인자는 로컬변수의 특성을 갖는다.
  • 함수안에서 값이 변경되어도 외부 변수값은 변경되지 않는다.

Call by Reference(참조에 의한 호출)

  • 함수가 호출될 때, 메모리공간에서 함수를 위한 별도의 임시공간이 생성된다. (메모리 스택공간)
  • 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다.
  • 함수에서 인자값이 변경되면 레퍼런스가 가리키는 외부변수의 값 또한 변경된다.

Java는 Call by Value일까 Call by Reference일까

  • 기본자료형은 Call by Value고 참조자료형은 Call by Reference아닌가??
public class FunctionCallTest {
  public static void assignNewPerson(Person p) {
    p = new Person("hee");
  }
  public static void changeName(Person p) {
    p.setName("hee");
  }

  public static void main(String[] args) {
    Person p = new Person("doy");

    assignNewPerson(p);
    System.out.println(p); // name is doy

    changeName(p);
    System.out.println(p); // name is hee
  }
}

오해 1 . 특정 메서드 내에서 전달받은 객체의 상태를 변경 할 수 있다.

  • changeName 메서드는 참조변수 p가 가리키는 [이름 속성이 "doy"인 Person 객체]를 [이름 속성이 "hee"인 새로운 Person 객체]로 변경한 것이 아니라, 단지 이름 속성만 변경했을 뿐이다.

오해2. 참조변수는 레퍼런스를 저장하므로 메서드로 전달된값이 레퍼런스다(call by ref)

  • 전달된 레퍼런스는 참조변수 p(스택공간에 메모리) 자체의 레퍼런스가 아닌 p가 저장하고 있는 값(레퍼런스!)이다.

  • 만약 자바가 call by ref였다면 assignNewPerson을 호출한 이후에 참조변수 p가 새로운 객체를 할당받아 print하면 hee가 나와야하는데 doy가 나옴 →즉, p자체의 레퍼런스가 아닌 p의 값이 복사되어 전달된것임

정리하자면, 객체의 주소를 보내는것은 맞지만 그 주소 또한 참조변수의 메모리공간에 담겨있는 '값', 이 복사되어 전달되기때문에 call by value라는것이다.

 

 

출처:

https://github.com/WeareSoft/tech-interview

https://sleepyeyes.tistory.com/11

https://re-build.tistory.com/3