학습 목표
참조 공유와 클래스 공유 변수를 따로 표시한다.
본문
핵심 이론
Java에서 객체 변수는 객체 자체가 아니라 참조값을 가진다. b=a는 같은 객체를 가리키게 하며 new는 새 객체를 만든다. a==b는 참조 동일성을 검사한다.
인스턴스 필드는 객체마다 따로 있고 static 필드는 클래스에 속해 공유된다. 참조 두 개가 같은 객체를 가리키면 인스턴스 필드 변경도 함께 관찰된다.
static 메서드는 객체별 this를 가지지 않는다. final 참조는 재대입을 제한하지만 참조 대상의 모든 필드를 불변으로 만들지는 않는다.
객체를 함수에 전달한 뒤 필드를 바꾸는 경우와 매개변수만 다른 객체로 바꾸는 경우를 구별한다. 생성된 객체 수와 참조 변수 수는 다를 수 있다.
개념 도식
Java 참조 변수는 객체 자체가 아니다
Box a=new Box(); Box b=a;에서는 객체 하나에 a와 b라는 참조가 연결된다. b.value=7을 하면 a.value로 읽어도 7이다. 반면 b=new Box()는 b의 연결만 새 객체로 바꾸므로 a는 이전 객체를 계속 가리킨다.
| 실행 | a의 대상 | b의 대상 | a.value |
|---|---|---|---|
| b=a | 객체 1 | 객체 1 | 초기값 |
| b.value=7 | 객체 1 | 객체 1 | 7 |
| b=new Box() | 객체 1 | 객체 2 | 7 |
매개변수에도 참조값의 복사본이 전달된다. 메서드 안에서 매개변수 b를 새 객체로 재대입해도 호출자의 a는 바뀌지 않는다. 같은 객체의 필드를 수정하면 호출자에게도 보이는 것은 양쪽 참조가 같은 저장 공간에 닿기 때문이다.
인스턴스 필드는 객체마다 별도이고 static 필드는 클래스에 속해 공유된다. 새 객체 두 개를 만들면서 각 생성자가 static count를 증가시키면 count는 누적되지만 각 객체의 일반 필드는 독립적이다. 출력 문제에서는 객체 번호와 필드 값을 표에 써서 공유 여부를 확인한다. 배열도 객체이므로 이 규칙을 그대로 적용한다.
풀이 예시
다음 Java 17 프로그램이 표준 출력에 기록하는 내용을 쓰시오. 마지막 줄바꿈의 유무는 답안에서 구별하지 않는다.
public class Main {
static class Pass {
static int issued = 0;
int number;
Pass(int gap) { issued += gap; number = issued; }
}
public static void main(String[] args) {
Pass a = new Pass(2);
Pass b = new Pass(3);
Pass.issued += a.number;
System.out.println(a.number + "," + b.number + "," + Pass.issued);
}
}
정답과 풀이 보기
예시 정답
2,5,7
풀이 과정
issued는 모든 인스턴스가 공유한다. 생성 후 a.number=2, b.number=5이며 공유 변수만 추가로 2 증가해 7이다. 각 인스턴스 번호는 나중에 함께 바뀌지 않는다.