최근에 공부하는데 내 앞길을 막는 녀석

뭐, 별건 아니고 그냥 공부하는데 방해되는 개념이 있어서 이 녀석 욕도 좀 하고
욕하는 김에 완전히 이해해버릴 요량으로 뻘글 하나 올립니다.

우선 이 녀석이 갑자기 헷갈리기 시작한 곳은 Linked List의 addFirst 함수 구현하는 와중이었습니다.
앞뒤 다 자르고 보면 이런 녀석이었죠.

protected void addFirst(int input){
     node newNode = new node(input);
     newNode.next = head;
     head = newNode;
     size++;
}

이때 갑자기 뇌절이 온겁니다.

newNode.next = head;
head = newNode;

‘아니 이 자식은 뭐지 대체?’
조금만 공부해보면 어떤 구조인지 알수있었겠지만
맨처음, 머릿속에 떠오른 그림은 이런거였습니다.
image
그야말로 세상을 왕따시키고 혼자만의 세상에 틀어박힌 힙스터가 되어버린 코드…
어떤 키워드로 검색해야 이것에 대한 답을 찾을 수 있을까? 하는 찰나에 제 머릿속에서 Pointer에 대한 개념이 떠올랐습니다.
자바에는 pointer라는 개념은 없지만 혹시나 Object의 이름은 데이터가 아닌 특정한 메모리 영역을 나타내는 것이 아닐까?
갑작스런 로–직갓이 내린건지 상당히 설득력 있어보이는 가설을 한가지 도출해냈고(씁씁한 이야기지만 만약 제가 구글링의 신이었다면 한 3분만에 해답을 찾을 수 있었을 겁니다, 이 글은 어디까지나 제 삽질에 대한 썰을 푸는 것입니다.이런것도 재밌긴하지만 천날만날 이런것만 하다보니 빡이 칩니다흐규흐규)
그렇다면 저 두줄의 코드에 들어갈 주석은 이렇게 될 터입니다.

newNode.next = head;
//head라는 메모리에 저장된 '값'을 참조하여 newNode.next를 초기화한다.
head = newNode;
//newNode에 저장된 '값'을 head라 이름붙인 '메모리 공간'에 push한다.

해당 가설에 관련된 질문을 해시코드에 올렸고(java - 객체를 대상으로한 대입 연산자는 어떤 기능을 하나요? | Hashcode) 긍정적인 답변이 돌아왔습니다.

결론적으로 정리하자면

object A(dataA);
object B(dataB);
A = B;

의 구조를 가진 java code는 C언어로 따지자면

int a, b;

int* aPtr = &a;
int* bPtr = &b;

a = *bPtr;

라는 해괴한 구조를 가진 코드와 같은 작용을 한다는것
후…개어렵네…★

1 Like

잘하셨네요 ㅎㅎㅎ

객체타입은 C로 따지면 포인터 래핑되어있다고 생각하시면 편합니다.
C++로 따지면 레퍼런스 형태인거죠.

자바의 객체형은 레퍼런스로 사용되니까요.

object a = new object();
object b = a // a,b같이 위의 new object()로 생긴 객체를 가리킨다.
object a = new object(); //a는 새로운 객체를 가리키고 b는 여전히 기존의 객체를 가리킨다.

실제 객체는 항상 Heap영역에 있고, 변수 a는 그걸 가리키기만 한답니다.
스코프가 끝나서 변수 a또는 b가 해제되면 Heap에 있는 객체를 가리키는 변수가 없어지고
그러면 가비지컬렉팅의 대상이 되는거죠 ㅎㅎㅎ

1 newNode.next = head;
2 head = newNode;

같은 맥락으로 보면,
예전 head에 있는 객체를 next가 가르키는거고, 새로운 head는 newNode가 되니까요.
결국 맨 앞에 새로운 노드를 삽입하는거죠. ㅎㅎㅎ

명령형 언어에서 갖는 실행과 변수 패러다임을 보면,
명령은 순차적으로 실행되고, 변수는 메모리공간을 표현하는 이름일 뿐이죠.
1 newNode.next = head;을 실행한다고 해서 앞으로 계속 next와 head가 같은건 아니에요.
그냥 head가 갖는 값을 next에 복사해 넣은거죠.

PS. 물론 JAVA의 string은 다르게 동작하겠지만요 ㅎㅎㅎ
한번 잘 살펴보세요.

1 Like

왜 저는 이리 설명을 못할까요
쓰고나서 읽어보니 좀 장황해 보이네요.ㅜㅜ

핵심은 이겁니다.

  1. 순차적으로 실행하기에 나중에 실행되는 코드는 이전에 실행되는 코드에 영향을 주지 않는다.
  2. 변수의 대입은 두 이름이 같아 지는게 아니라 메모리 값을 복사하는 거다.
1 Like