코드 그라데이션
Day16 makeB() 자료 보충공부 본문
Case1
B makeB(){
b = new B(); //B 객체를 생성 선언되어 있는 변수 b에 대입
return b;
}
매번 makeB()를 하면 new를 해서 b를 만든다.
새로운 객체를 매번 넣어준다는 소리다.
클래스 B에 있는 k는 객체에 붙는다.
(static 없으므로)
1)에서 a 객체를 만들고
2)에서 a에서 makeB()를 한다. 이 때 B라는 객체가 생길 것이고, 그 결과를 b1이라는 변수에 저장.
즉 b1과 B 객체가 연결
3)에서 b1을 타고 들어와서 k에 10 값을 대입.
4)는 a를 통해서 b에 접근해서 b에 있는 k에 20을 대입.
즉, b1.k와 a.b.k는 위치가 같다.
지금 위 그림에선 편의를 위해 노란색 상자 B를 A 내부에 집어넣은 것처럼 표현했지만,
사실 정확히 말하면, b도 참조변수이기 때문에, A도 B를 객체 자체로 가지고 있는 게 아니라
주소만 어디있는지 가지고 있는 것.
그래서 밖에 그려주는 게 더 정확하다.
여기서 주의!!
조금 헷갈릴 수 있는 부분은 다음과 같다.
지금 makeB()는 new B()를 통해 객체를 만든 다음에그 결과를 b에 담아서 그 b를 리턴하고 있다.그런데 이 b는 클래스 A가 가지고 있는 필드이다.그 관계 명심.
-------------------헷갈린다면,
class A{
B b;
B makeB(){
B newB = new B();
return newB;
}
}
class B{
int k;
}
이런 상황이라면, 이때의 객체는 makeB() 내부에서 만든 변수
newB는 makeB() 가 끝나면 죽는다.
그러면 아래 식에서
A a = new A(); // 1
B b1 = a.makeB(); //2
b1.k = 10;
이 newB는 b1에만 깔끔하게 담긴다.
이 때 a.b.k = 20; 은 에러가 난다!!!!
b는 만들어진 적이 없으니까.
즉 다시 원래 상황으로 가면, makeB() 에서 새로운 객체를 b에다가 꼽고, b를 리턴한다.
그 b 객체가 A클래스에서 필드(b)로 알고 있다.
그래서 a.b.k가 가능하게 된 것.
마지막으로, 그림으로 정리하자면
또 한 가지 유의
a.b.k는 객체가 생성되었기 때문에 접근이 가능한 것.
만약에
A a = new A(); // 1
a.b.k = 30; // 여기서 하면
B b1 = a.makeB(); //2
b1.k = 10;
컴파일 에러가 발생할 것.(nullpointException)
최종정리, 헷갈림 방지하기 위해 보자면
class A{
B b;
B makeB(){
this.b = new B(); // 이렇게
return this.b;
}
}
class B{
int k;
}
이렇게 써주는 게 가장 속 편한 방법이다.
Case2
Case1과 비슷하지만,
새로운 객체를 하나 더 생성.
따라서 a.b.k를 부르면, 로직은 동일하지만 두 번째 생성된 객체에 도달할 것이다.
그건 k=20; 이 되는 것이다.
하지만 마지막 식에서 b1에 k를 불렀으므로 10.
A와 b1의 연결관계는 매번 새롭게 makeB()가 주어지므로, 끊어진다.
'Java > Mega' 카테고리의 다른 글
클래스배열 초기화(생성자에서) 예시 (0) | 2023.04.09 |
---|---|
Day16. HasTest 보충 (0) | 2023.04.09 |
Day19. HasTest2(Has관계) 두 번째 예제 설명 (0) | 2023.04.08 |
Day19. 문방구 퀴즈 <제품 구매> 공통 코드 (0) | 2023.04.08 |
Has 관계 예제 (0) | 2023.04.05 |