TMI
자바를 공부하다보면 '참조' 라는 단어를 많이 보셨을거에요
이 '참조'라는 것을 공부를 해도...강의를 들어도.. 느낌상으로는 대충(?) 알겠지만 막상 온전히 제 것이 되는 느낌은 받지 못하셨던 분들을 위해 글을 써보겠습니다.
(사실 제가 리마인드 차원에서 쓰는 글이에요,,, )
얼마전에 자바를 입문한 친구가 참조를 정확히 자신에게 설명해줘라 라고 했을 때 "아 이게 그러니까..음 인스턴스가 있고 ,,," 뭐 깔끔하게 정리해서 설명이 잘 안 되더라구요 🤣
그럼 이제 '참조'란 무엇인지에 대해서 말해보겠습니다.
참조란
(아래 예제는 생활코딩-참조 편을 인용했습니다.)
int a = 1;
int b = a;
System.out.println(a);
위의 코드에서 출력은 어떻게 될까요? 당연하게도 1이 나오죠!
a라는 변수에 1을 저장했고 b에서 a에 들어있는 값인 1이 b에 '복제'가 되는 것이죠.
위에 애들처럼 primitive type인 경우에는 이해하기도 쉽고 단 번에 알아채셨을 거에요. 왜 그렇게 되는지 이유까지도요.
이번엔 객체를 예로 들어보겠습니다.
class A {
public int myId;
A(int myId) {
this.myId = myId;
}
}
A a = new A(4);
A b = a;
b.myId = 5;
System.out.println(a.myId)
위의 출력은 어떻게 나올까요?? 4?? 5??
정답은 5입니다. 여기서 잠깐이라도 4라고 생각하신 분들은 ! 글을 끝까지 읽어주세요.
설명을 드리기 앞서 한 가지 말씀드릴 것이 있어요!!!!!!!
주소값이라는 단어가 많이 나올텐데 제가 여기서 말씀드리는 주소값은 메모리 주소를 말하는 것이 아닙니다!
이에 대해 간단하게 설명을 해보자면 JAVA에는 primitive type(기본타입)과 reference type(참조타입)이 있습니다.
primitive type은 java의 메모리 구조 중 Stack 영역에 직접 값을 가지고 있고 reference type은 Heap 영역의 객체 주소를 Stack 영역에 갖고 있어요.
여기서 말씀드리는 주소값은 Stack영역에 갖고있는 heap영역의 객체 주소를 말하는 것입니다.
(너무 길어지는 것 같은데.. 참고로 C++의 포인터는 메모리 주소 자체를 관리합니다!)
a(참조변수)는 new 생성자로 만들어진 클래스 A의 인스턴스가 있는 주소값을 갖게 됩니다.
(즉, 앞선 예제에 있는 primitive type 예제 처럼 4라는 값이 a에 저장되는 것이 아닌 myId값이 4인 클래스 A의 인스턴스가 있는 주소값이 저장되는 것이죠)
이 때, 이것을 참조라고 하고 위에서 말하는 주소값을 참조값이라고 하는거죠.
A b = a; 이 부분을 보면 b라는 참조변수는 a가 갖고있는 인스턴스 A에 대한 주소값(참조값)을 갖게 됩니다.
이제 b.myId = 5; 는 클래스 A를 이용해서 만든 인스턴스가 갖고있는 myId 값을 5로 변경을 하는 것이에요.
자 이제 System.out.println(a.myId) 부분을 정리해보자면 변경된 myId 값(5)를 갖고있는 클래스 A를 이용해서 만든 인스턴스가 있는 주소값을 가리키는 참조변수 a의 myId값을 출력하는 것이니 5가 출력이 되겠죠!!
이해가 되셨나요?
되셨으면 좋겠네요,,
혹여나 틀린 부분이나 질문이 있으시다면 댓글로 남겨주세요!
'gyub's 공부일기 > Java' 카테고리의 다른 글
[ JAVA ] 자바는 call by value? call by reference? (1) | 2021.03.27 |
---|---|
[JAVA] JVM 클래스로더 (0) | 2020.12.10 |
[ JAVA ] JAVA의 동작 방식와 JVM 메모리 구조 (0) | 2020.11.30 |
[ JAVA ] Java의 특징 및 JVM, JDK, JRE (0) | 2020.11.29 |