공부공부/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