달력

3

« 2024/3 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2016. 12. 18. 17:14

Java의 인자 전달 방법 Basic Languages/Java2016. 12. 18. 17:14

Java의 parameter를 전달하는 방법에 대해서 call by value인지 call by reference인지 인터넷에 보니 이야기가 엇갈리는 것 같다.


먼저 아래 예제를 보고 출력되는 결과값을 예상해 보자.



출력 결과는?

temp.num은 200

temp는 왠지 null이 나오지 않을까 의심했을 수도 있겠지만 Temp@해시코드값이 나온다.


이게 뭐? 당연한 거 아닌가? 라고 생각하는 사람은 제대로 이해하고 있는 것.

헷갈린다면 아래의 설명을 읽어보자.


위 검정색 테이블은 메모리다(Java가 메모리를 어떻게 관리하는지는 따로 공부하기로 하고, 일단은 실제 메모리라고 생각하고 보자)


메인함수를 보면 가장 먼저 Temp클래스로 인스턴스를 하나 만들었다.

메모리의 13번지에 인스턴스가 만들어졌다. 근데 인스턴스만 있으면 아무것도 못한다. 그 인스턴스가 13번지에 있다는 것을 프로그램이 알고 있어야 의미가 있을 것이다.


그러므로 인스턴스의 위치를 저장하는 변수가 필요하다. 그게 바로 레퍼런스 변수다. 여기서는 temp라는 이름으로 레퍼런스 변수를 만들었고, 그 temp는 메모리 그림을 보면 0번지에 만들어져 있다. 또한 13이라는 주소값을 저장하고 있다.


그럼 이제는 objectRemover란 함수에 현재 만들어진 temp를 전달해 보자.

여기가 아마 사람들이 헷갈리는 부분일 것이다.

분명 레퍼런스를 전달했으니, objectRemover()의 제일 마지막 줄에서 t = null 처리했으니 메인함수의 temp도 null이 되지 않았을까? 라고 생각하기 쉽다.

하지만 막상 메인메소드로 돌아와서 콘솔에 찍어 보니 null이 나오지 않는다.


메인의 temp가 null이 되지 않은 이유는 뭘까?

답은 메인의 temp는 objectRemover의 t와 다른 변수이기 때문이다.

레퍼런스를 전달했다는 말은 13이란 값을 전달했다는 뜻이다.

근데 objectRemover()메소드가 만들어질 땐 13이란 값이 전달이 된 것은 맞지만, 13이란 값이 저장된 저장소가 전달된 것은 아니다.


위 그림을 보면

temp라는 이름으로 0번지에 13이 저장되어 있고,

t라는 이름으로 21번지에 13이 저장되어 있는 것이다.

즉, 레퍼런스 변수는 복사된 것이란 뜻이다.


말로 풀어서 설명하니 제대로 설명이 된지도 모르겠고, 오히려 이해만 어렵게 한 것 같기도 하다.

결국 위 그림의 메모리맵과 빨간색 화살표가 핵심이다. objectRemover메소드가 호출될 때 참조변수가 복사됐다는 것만 알면 된다.

참조변수가 복사되었으니 그 참조변수의 13이란 값을 null로 변경해봤자 원본 참조변수는 아무 영향이 없는 것이다.



....그냥 그림만 보자. 말로 하는 설명이 이해하기 더 힘든 것 같다......

:
Posted by 클레잇