Study · JDK · STEP 6 / 8 · 실행할 때

같은 덧셈을 객체 필드에 하면, 바뀌는 곳이 힙으로 옮겨 간다

장면

Box b = a; 뒤에 a.total만 바꿨는데 b.total을 찍었더니 15가 나왔다. 왜일까?

public class Box {
    int total;

    public static void main(String[] args) {
        Box a = new Box();
        Box b = a;
        for (int i = 1; i <= 5; i++) {
            a.total += i;
        }
        System.out.println(b.total);
    }
}

아래 재생기의 ▶를 누르면 한 스텝씩 진행된다. 금색 테두리가 지금 이야기하는 곳이고, 캡션이 무슨 일이 일어났는지 말해 준다. 굵게 밑줄 친 말은 누르면 뜻이 나온다. 빨간 딱지는 그때 벌어지는 일의 이름이고, 캡션 바로 위 회색 글자는 지금 스텝이 속한 묶음의 이름이다.

카드 아래 회색 줄은 그 일이 실제로 적혀 있는 소스의 파일 이름 : 줄 번호와 함수 이름이다. 글 안에 (:669)처럼 줄 번호만 적힌 것은 바로 앞에 적은 파일의 그 줄이라는 뜻이다. 캡션 한가운데 박힌 긴 영어 이름과 괄호 속 파일 · 줄 번호도 같다 — 건너뛰고 한글만 읽어도 뜻이 통하게 써 두었다.

장면 · 객체 필드에 더하기 0 / 24

아직 객체가 없다. 칸 0(args)은 이 장면에서 쓰지 않아 화면에서 뺐다. ▶를 누르면 new가 힙에 Box를 만들고, 칸 a · b에 참조가 들어가는 과정부터 본다.

키보드 · ← → 한 스텝 · Space 재생/멈춤 · Home 처음

칸 a와 b에는 객체가 아니라 같은 객체를 가리키는 참조가 들어 있다. 힙의 Box는 하나뿐이라, a로 쓴 값을 b로 읽을 수 있다.

어떻게 확인했나

소스 어디를 보고 적었는지와 무엇을 돌려서 쟀는지를 남긴 자리다. 처음 읽을 때는 건너뛰어도 된다.

  • a와 b가 같은 객체(id=530)라는 것과 반복마다의 total 값은 jdb로 읽은 실제 값이다.
  • @530은 jdb가 객체를 구별하려고 붙인 번호다. JVM 안에서 참조가 쓰는 실제 값은 아니다.
  • 칸 크기는 javap 출력이다 — stack=3, locals=4. 스택 값은 명령의 뜻대로 따라가 그렸다.