[java] Call by Reference 와 객체 생성

Yoen-ik Jo (여니기)·2020년 10월 20일

처음 java를 배울 때 c언어의 포인터처럼 주소에 의한 호출을 하려면 객체를 전달하면 된다고 배운적이 있다.

완전히 같진 않지만 메소드 파리미터에 객체를 넘기게 되면 주소가 넘어가기 때문에 포인터처럼 쓸 수 있다는 것.

그런데 언제와 같이 개발을 하던 도중, 메소드에 객체를 넘겨서 DB에서 조회한 정보를 할당한 뒤 호출지점으로 돌아왔는데 할단된 데이터가 증발하는 일이 일어났다.

아주 여상스럽게 쓰던 방식이 통하지 않으니 당황하여 원인을 찾아본 결과 java에서 포인터처럼 쓰던 방식에 주의해야할 함정이 있음을 알게 되었다.


a = new A();

객체를 선언하게 되면 java에서는 A객체 데이터를 저장한 공간의 주소를 a 변수에 할당하게 된다.

func(a);

선언된 객체 변수를 메소드의 파라미터로 넘기는 순간 java는 a' 라는 새로운 변수에 A객체 주소를 할당하게 된다.

즉, call by value 방식으로서 파라미터가 전달되지만 a 변수에 할당된 데이터가 주소이기 때문에 주소를 넘김으로서 call by reference처럼 동작하는 것이다.

a' = new A'();

그런데 func() 메소드 내부에서 파라미터에 새로운 객체 A'를 할당하는 순간 a' 변수에는 새로운 객체주소가 할당되게 되고,

stack 구조에 따라 당연하게도 해당 메소드를 벗어나는 순간 a' 변수는 휘발되어 새로 할당된 A'의 데이터는 할당하지 않은 상태가 되어

원 호출지에서 a 변수를 다시 사용하려고 하면 처음 A 객체의 데이터만 사용되는 것이다.


정리하니 이렇게 동작하는 것이 정말 논리적으로 당연하게 느껴진다.

사실 c언어의 포인터도 같은 방식으로 동작하는 것이 아닐까? 다만 객체가 없어서 확인을 못하였을 뿐.

어쨌든 아둔한 초보 개발자인 나에게 굉장한 깨달음이었으니 메모메모.

profile
배워가는 초보개발자

0개의 댓글