Call by value, Call by reference ?

 

 위 두 내용은 메소드(함수)에서 인자값을 받을 때 어떤식으로 받아 올 것 인지에 대한 방식이다.

 뜻 그대로 '값에 의한 호출' 그리고 '참조에 의한 호출' 인데 그 내용은 예시를 들어 설명해보겠다.


 

 Call by value


메소드 호출 시에 사용되는 인자의 메모리에 저장되어 있는 값(value)을 복사하여 보낸다.

무슨 뜻이냐면 int a =3 이라는 문구가 있으면 

메소드에서 인자값을 받을 때 a라는 자체에 주소를 받는게 아니라 a의 값인 3을 받아 처리하는 방식이다.


 Call by reference


메소드 호출 시 사용되는 인자 값의 메모리에 저장되어있는 주소(Address)를 복사하여 보낸다.

값이 아니라 인자 그자체에 주소 값을 보낸다. 




결론을 먼저 말하자면 자바는 Call by value  방식으로 인자값을 받는다.





결과 값은 이렇다
비포
안녕잘가
에프터
안녕잘가


 왜 스왑 메소드를 이용해서 서로를 바꿔준 것 같지만 바뀌지 않았을까?? Call by value 방식이기 때문이다. 

스왑 메소드가 받는 두 인자는 인자값에 주소 즉 인자 그자체를 받는 것이 아니라 인자의 값을 복사해서 받는다.

즉 String one 에는 a에 값인 "안녕" 에 값이 (String 은 참조 변수 이므로 "안녕" 에 주소 값이 복사)

마찬가지로 two 에도 b의 주소가아닌 b값에 주소가 복사 되어진다.




 이렇게 메인 메소드의 a, b와 swapS 메소드의 one two는 서로 같은 값을 참조할 뿐 이다.

 이렇게 메소드 내에서는 변화가 이루어 지지만 메소드가 닫히면 swapS에 있던 정보는 다 사라지므로 메인 메소드에 영향을 주지 못한다.

만약 위 코드에 있는 //주석문을 활성화 시키면 바뀐 값을 출력 할 것이다.



 만약 call by Reference 방식 이였으면 메소드내에서 one two가 a, b의 주소값을 받아 곧 a=one b=two 이고 메소드 수행으로 서로값이 바뀌니 메소드 수행을 하고 나서도 a, b가 바뀌어 있을 것이다. 



하지만 이러한 효과를 내는 방법은 있다.





swap() 호출 전 : a = 10, b = 20

swap() 호출 전 : a = 20, b = 10


이렇게 값이 바뀌는 걸 볼 수 있다.


그림으로 보자

 

마찬가지로 one과 two는 값의 주소를(call by value) 복사받아 같은 인스턴스를 참조하는 것 이지만..



이렇게 참조 되어지는 값을 바꾸어 주어 마치 call by reference 가 이루어진 것 처럼 보인다.


비슷한 예로 


1 8
8 1

이렇게 가르키고 있는 공간의 값을 바꾸어 주면 된다.




정리하자면 !!

자바는 !

기본형 타입 변수와 참조형 타입 변수가 있는데 

둘 다! 상관없이 call by value 방식으로 메소드에서 받아진다 !


대신 기본형 타입은 그 값을 복사 해서 주지만

참조형 타입은 값의 래퍼런스(주소)가 저장되는 것이므로 그 값의  래퍼런스가 복사 되어진다 !


즉 값의 래퍼런스가 call by value 방식으로 넘어간다!.


말이 긴데 어찌되었든 call by value 방식이다 자바는..



참조

http://hyoje420.tistory.com/6

http://re-build.tistory.com/3#comment14570096

http://purple-dev.tistory.com/36

https://brunch.co.kr/@kd4/2

https://muckycode.blogspot.com/2017/07/java-paratmeter-call-by-reference-vs.html

http://history1994.tistory.com/8?category=668240

+ Recent posts