6.2.1 객체 생성하기

jh·2022년 1월 26일
0

Do it! 자바 완전 정복

목록 보기
53/70

6.2 객체의 생성과 활용
이번에는 클래스로 객체를 생성하고 활용하는 방법을 알아보자. 붕어빵 이야기로 비유하면 붕어빵 기계(클래스)에서 붕어빵을 찍는 방법(객체 생성)과 붕어빵을 맛있게 먹는 방법(객체의 활용방법)을 알아보는 것이다.

6.2.1 객체 생성하기
객체는 new 키워드로 생성할 수 있다. 자바에서는 대부분의 클래스가 이 방법으로 객체를 생성한다. 클래스에 따라 메서드를 사용해 객체를 생성할 때도 있지만 이때도 해당 메서드 내부에서 new를 사용해 객체를 생성한다. 즉 모든 클래스가 객체를 new 키워드로 생성한다고 볼 수 있다.

🐶클래스의 객체 생성

클래스명 참조 변수명 = new 생성자();A a = new A();

객체 생성 코드를 구성하는 요소를 앞에서부터 살펴보자. 첫 번째는 클래스명, 두 번째는 참조 변수다. 참조 변수는 실제 데이터를 저장하는 것이 아니라 실제 데이터가 있는 힙 메모리의 위칫값을 가리키는 변수를 말한다고 했다. 세 번째는 new 키워드로 '~을 힙 메모리에 넣어라'는 의미다. 마지막은 생성자다. 클래스와 이름이 동일하지만 뒤에 소괄호가 붙어있다.
이 생성자가 실행되면 클래스의 객체가 생성된다. 따라서 new는 생성자의 결과물로 나온 객체를 힙 메모리에 넣는다.

그런데 실제 데이터를 저장하고 있는 객체를 힙 메모리의 어느 위치에 넣었는지 알려 주지 않으면 그 객체를 쓸 방법이 없다. 그래서 힙 메모리에 실제 객체를 넣을 때 그 위칫값을 변수에게 알려 주는 것이다. 위 객체 생성 예시에 포함된 코드를 다시 한번 말로 표현하면 'A() 생성자로 만든 객체를 힙 메모리에 넣고 위칫값을 A 타입의 참조 변수 a에 저장하라.'고 표현할 수 있다. 몇 줄 안 되는 설명이지만 어쩌면 책에서 가장 중요한 부분일 수 있다. 자바는 클래스 기반이고 모든 클래스에 적용되기 때문이다.

객체 생성에 따른 메모리 구조 살펴보기
이제 객체를 생성했을 때 메모리에 어떻게 저장되는지를 그림을 이용해 살펴보자.

클래스 A는 메모리의 클래스 영역, 참조 변수는 스택 영역에 들어간다. 내부 공간에는 실제 데이터(객체)의 위칫값을 저장한다. 생성자로 만들어진 객체는 힙 메모리에 위치하며 객체 내부에는 클래스의 멤버(필드, 메서드, 이너 클래스)가 위치한다. 이제 객체에 포함된 3가지 요소가 사용할 수 있는 상태가 된 것이다. 그런데 메서드를 살펴보면 실제 메서드 구현 코드는 클래스 영역 안에 저장해 놓고, 객체 안에서는 메서드 영역의 위치만 가리키고 있다는 것을 알 수 있다. 그 이유는 1개의 클래스로 만든 모든 객체는 속성(필드)은 달라도 기능(메서드)는 동일하기 때문이다. 즉, 객체를 100개 만들어도 메서드는 한 번만 만들면 된다는 뜻이다. 자동차 클래스로 빨간색 자동차와 파란색 자동차를 하나씩 만드는 그림을 살펴보자.

자동차 클래스로 빨간색 자동차 객체와 파란색 자동차 객체를 만들면 힙 메모리에 각 객체가 저장된다. 빨간색 자동차의 color 속성값은 'red', 파란색 자동차의 color 속성값은 'blue'라고 가정해 보자. 둘다 drive(기능)이 있어야 하므로 두 객체 안에 drive()메서드가 포함돼 있어야 한다. 그런데 각 객체에 포함돼 있는 drive()메서드 코드가 동일하므로 이를 메서드 영역에 1개만 만들어두고 모든 객체가 공유하는 것이다.
여기서 '자동차마다 성능이 다르지 않아요?', '성능이 다르면 drive() 메서드도 다르지 않나요?'와 같은 질문을 하는 사람도 있을 수 있다. 당연하다. 하지만 성능이 다르다는 건 다른 클래스의 객체라는 의미다. 즉, '다른 붕어빵 기계로 찍은 붕어빵'이라는 이야기다. 다른 클래스로 생성된 객체의 메서드이므로 당연히 메서드를 공유하지 않는다. 다시 말해, 동일한 클래스로 만든 객체들은 기능(메서드)의 내용이 동일하므로 메서드를 공유할 수 있는 것이다.

예제로 메모리 구조를 직접 살펴보기
이제 실제 예제로 객체를 생성하고 메모리의 구조를 살펴보자. 클래스 A에는 다음과 같이 필드 1개와 메서드 1개가 있다. 필드값 m은 3으로 초기화돼 있으며, print() 메서드는 간단한 문자열을 출력하고 있다.

class A { 
int m = 3; 
void print() {
System.out.println("객체 생성 및 활용");
}
}

이 클래스의 객체 생성 코드와 객체 생성 이후의 메모리 구조는 그림과 같다.

앞에서 살펴본 예제를 실제 데이터로 바꾼 정도이므로 쉽게 이해될 것이다. 여기서는 생성된 객체에서 필드값은 실제 저장공간이 객체 내부에 있고, 메서드는 메서드 영역에 있는 1개의 메서드를 공유하고 있다는 점만 기억하자.

profile
코딩 공부 중...

0개의 댓글