자료구조 공부 중 연결 리스트에서 addLast 메소드 부분을 보고 있는데 진짜 이해 안가는 부분이 있었다.
public void addLast(E obj) {
Node<E> newNode = new Node(obj);
Node<E> tmp = head;
while(tmp.next != null) {
tmp = tmp.next;
}
tmp.next = newNode;
}
라는 코드에서 tmp.next = newNode를 하면 tmp뿐만 아니라 tmp라는 변수에 저장된 노드에도 newNode가 저장된단다.
강의 듣는 와중에는 응응... 글쿤하고 지나갔는데 코드를 보면 볼수록 이해가 안가기 시작했다.
아니 진짜 말이 안되는게 변수 i에 변수a를 저장하고(i=a) i에 5를 저장했다고(i=5) 했다고 a가 5가 됐다는 소리 아닌가...;;
그래서 열심히 찾다가 자바에도 call-by-reference와 비슷한 개념이 있다는걸 발견했다. (역시 기본기가 탄탄해야한다는걸 깨달음 ^ㅠ)
자바에는 stack 영역이 있고 heap 영역이 있는데 기본타입(int, short, long..)들은 stack타입에 직접 값을 갖고 있고 참조타입(클래스)들은 heap영역에 값을 두고 stack에 heap 영역의 주소를 저장해 참조하는 방식으로 메모리를 관리한다.
(여기까진 다들 아시는 사실일 것이고)
그런데 내가 몰랐던 사실은 객체를 선언할 때마다 이 객체가 참조값을 기반으로 움직인다는 것이다.
class Test {
public String str;
Test(String str) {
this.str = str;
}
}
Test originalT = new Test("exp");
System.out.println(originalT.str);
Test newT = originalT;
newT.str = "changed";
System.out.println(originalT.str);
의 경우
1. oiriginalT라는 객체를 만들어서 그 객체에 exp를 저장하면 Test객체의 인스턴스(진짜 originalT)의 정보는 heap에 저장되고 그 주소(o라고 하자)가 stack에 originalT라는 이름으로 저장된다.
2. newT를 선언하고 originalT를 newT에 저장하면 우선 Test객체의 인스턴스인 찐찐 newT의 데이터가 heap에 저장되고 그 주소(n이라 하자)가 stack에 newT라는 이름으로 저장된다. 그후 originalT의 주소(o)가 newT의 주소(n)에 저장된다.
3. 결과적으로 newT의 주소 = originalT의 주소 = (o) 가 되어서 newT에 changed를 저장하면 (o)라는 주소에 changed를 저장하는 꼴이 되어서 newT뿐만아니라 originalT의 값도 바뀐다!!!
휴 드디어 이해 끝...
그러므로 내가 정리한게 정확하다면 자바는 기본 타입에 대해서는 call by value로 참조타입에 대해서는 call by reference로 작동한다.
또 자료구조 강의를 수강하며 계속 포인터 얘기를 하는건 자바에 포인터가 없음에도!! 주소값 전달을 설명하기 위해선 c의 포인터라는 개념을 차용하는 것이 유용하기 때문이다.
참조
'CS공부 > 자료구조' 카테고리의 다른 글
[Java] 해시함수의 충돌을 피하기 위해 테이블 사이즈를 소수, 홀수로 만들어야 하는 이유 (0) | 2022.12.08 |
---|---|
[Java] Iterator과 Iterable 그리고 iterator()을 알아보자(alaboza..) (0) | 2022.12.02 |
[Java] 연결리스트의 remove 메소드에서 오버라이드 없이 compareTo를 사용한다? (0) | 2022.12.02 |
[Java] 자바로 구현한 연결리스트(single linkedlist) addLast 메소드 쉽게 이해하는 법 (0) | 2022.11.29 |
[Java] 자바로 구현한 연결리스트(single linkedlist) addFirst 메소드 잘 이해하는 법 (0) | 2022.11.29 |
댓글