코드 그라데이션

Day16 makeB() 자료 보충공부 본문

Java/Mega

Day16 makeB() 자료 보충공부

완벽한 장면 2023. 4. 8. 23:56

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()가 주어지므로, 끊어진다.

 

728x90
Comments