[CS] 자바의 정석 독서 #8 - 생성자와 초기화

2025. 10. 1. 20:35·언어공부/Java | Kotlin

이 부분이 이전에 헤드퍼스트자바 읽을 때 좀 아리송했는데 이참에 좀 제대로 개념을 잡았으면한다.

솔직히 생성자와 초기화가 간단하지 왠지모르게 이해가 잘 안되는 부분이 있었는데, 이번에 좀 찾아보자


생성자

생성자 역시 메서드의 일종이다. 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드다. 하는 일은 인스턴스 변수를 초기화하는 것이며, public 이나 private 등 접근권한 정도만 선언하고 반환형태 역시 선언하지 않는다. 왜냐하면 반환값이 없기 때문이다.

생성자 역시 오버로딩이 가능하다.

 

Dog d = new Dog();

헤드퍼스트로 처음 자바 배울 때 많이 나왔던 코드

new는 연산자다. 이 연산자 new를 통해 인스턴스가 생성된다. 생성자는 인스턴스를 생성하지 않고 오직 인스턴스 초기화만 진행할 분이다.

 

new 연산자는 힙메모리에 메모리공간을 할당하고, 메모리주소를 반환하고, 생성자를 실행한다. 모든 참조형 변수는 객체 그 자체를 저장하는 것이 아니라 메모리주소를 저장하므로, new 연산자를 통해 얻어진 메모리주소에 있는 값을 참조하고, 값을 변경하고 하는 것이다.


기본 생성자

클래스이름() {}

꼴의 생성자를 기본생성자라고 한다. 클래스의 생성자가 없는 경우에 컴파일러가 자동으로 넣어주는 생성자

 

만약 생성자를 명시한다면 컴파일러가 생성자를 추가해주지 않으며, 따라서 직접 생성자와 초기화를 관리해야함에 유의해야한다. 가령 매개변수를 받는 생성자만 선언했는데 정작 객체를 생성할 때 매개변수를 전해주지 않는다던가..


매개변수 받기

class Member {
	String name;
    int age;
    
    Member() {}
    Member(String name, int age) {
    	name = name;
        age = age;
    }
}

...
Member member = new Member("윤마치", "28");
...

이렇게 선언할 수 있고 28세의 윤마치 Member 객체가 선언되었다. 매개변수를 통해서 값을 초기화할 수도 있다. 항상 나이가 0살인 null 선생님을 추가할 수는 없으니.. 또한 생성하고나서 값을 맞추는 것보다는 생성자를 통해서 한 줄로 객체를 생성하는게 좋기도하고, 나중되면 캡슐화 때문에 인스턴스에 직접 접근할 수도 없는데 그렇다고 세터를 쓰기도 그렇고 복잡한 빌더패턴을 쓰자니 단순 멤버객체 만드는데 너무 복잡하고..


this

생성자도 서로 호출이 가능하다. 그러나

 

- 생성자의 이름으로 this를 사용해야한다. (클래스명이 아니라)

- 반드시 첫 줄에서 호출해야한다.

 

라는 조건이 있어야한다.

생성자에서 초기화하다 다른 생성자를 초기화하면 기존 초기화하던 것이 초기화되어 기존작업이 무의미해질 수 있기 때문이다.

 

this는 인스턴스 메서드에 속한 자신을 가리키는 참조변수이다. 미리 등록되어있으며, 숨겨져있다.

 

class Member {
    String name;
    int age;
    
    Member(String name, int age) {
        this.name=name;
        this.age=age;
    }
    
    Member() {
        this("윤마치", 28);
        
        //this.name = "윤마치";
        //this.age = 28;
        //코드가 더 간결해졌다
    }
}

Member 객체에서 기본 생성자에서 this()를 통해 인스턴스 변수를 초기화하도록 했다.

이를통해 0세 null 씨가 등록되는 것을 막을 수 있다. 물론 this를 쓰지 않고 직접 인스턴스 변수에 접근할 수는 있지만 this를 쓰면 코드가 한 줄로 줄어들기에 더 간결하다. 수정도 쉽고 따라서 Member가 회원으로 들어오면 28세 윤마치씨가 기본적으로 등록된다.

 

또한 인스턴스 변수와 매개변수의 변수명이 같을 때, 어떤 것이 인스턴스 변수인지 어느 것이 매개변수인지 구분하기 어렵다. 따라서 인스턴스변수와 매개변수의 이름이 동일할 때는 인스턴스변수 앞에 this를 붙여 구분이 가능하도록 해야한다. 매개변수 이름을 다르게 하는 것보다는 this를 붙이는 것이 더 이해하기 쉽고 명확하다.

 

this는 오직 인스턴스 멤버만 사용할 수 있으며, 인스턴스 변수와 아무 관련이 없는 정적멤버는 사용할 수 없다. 이는 정적멤버가 인스턴스 변수를 사용할 수 없는 이유와 마찬가지이다.


생성자로 복제하기

기본적으로 Object 클래스는 clone() 메서드를 지원하여 인스턴스를 복사할 수 있다. 다만 생성자로도 인스턴스를 복제할 수 있는데,

 

Member(Member member) {
        name = member.name;
        age = member.age;
    }

이렇게 객체를 매개변수로 받는 생성자를 하나 만들어주면 된다. 이 코드가 실행되면 인스턴스 변수 값은 같은 두 객체가 만들어진다.

 

이렇게되면 new 연산자를 통해 생성자가 호출되면 생성자가 받은 member 객체를 통해서 새 객체를 형성하게 된다. 결과적으로는 인스턴스 변수가 동일한 두 객체가 만들어지게 된다.

 

이렇게 인스턴스 변수는 같지만 다른 두 객체가 만들어진다.

member1과 member2는 서로 독립적이기에 참조값도 다르고 수정해도 서로 영향을 끼치지 못한다.

 

    Member(Member member) {
        this(member.name, member.age);
    }

이렇게 this까지 활용하면 더욱 간결한 코드가 된다.

 

따라서 더욱 간결하고 직관적인 코드를 위해서는 다음을 고려해야한다.

1. 어떤 클래스의 인스턴스를 생성할 것인가?

2. 그 클래스의 어떤 생성자를 활용할 것인가>

를 고려해야한다.


변수 초기화

변수를 선언한 후 처음으로 값을 저장하는 행위를 초기화라고 한다. 보통 생성과 동시에 하는 것이 이상적이다.

 

정적변수와 인스턴스 변수는 자동으로 초기화가 진행된다. 숫자는 0, 문자열은 null, Boolean은 false로 자동 초기화된다.

이러한 점 때문에 타입을 정확히 알고있어야한다. 따라서 var 타입 (타입추론)은 불가능하다. 하지만 지역변수는 반드시 선언 후 초기화가 필요하다. 지역변수는 초기화가 자동이 아니다.

 

int i, long j = 10;	//안가능
int i = 10;		//가능
long j = 10;	//가능

타입이 다른 변수는 한 번에 초기화할 수 없다.


명시적 초기화

class Member {
	String name = "윤마치";
    int age = 28;
}

선언과 동시에 초기화하는 것. 명시적이고 간단하기 때문에 우선적으로 고려되는 초기화방법이다.


초기화 블럭

명시적초기화 과정이 복잡할 경우 블럭을 통해서 초기화할 수 있다.

 

초기화블럭은 인스턴스 초기화블럭과 정적초기화블럭으로 나뉘는데, 클래스 내에 중괄호로 블럭을 만들고 ({}) 거기에 static이 붙으면 정적, 아니면 인스턴스 초기화블럭이고 나머지는 동일하다.

 

class Member {
	{
    	//초기화블럭
        //여기에 원하는 초기화 로직을 넣으면 된다.
    }
    
    Member() { }
    
}

이런식으로..

초기화블럭에는 자유롭게 로직을 구현할 수 있으며, 생성자보다 먼저 실행된다. 따라서 초기화블럭에는 모든 생성자가 공통으로 실행해야하는 코드를 넣어두면 코드가 더 간결하게 작동할 수 있다. 또 재사용성도 높이고 중복도 제거하고, 이것이 OOP가 추구하는 목표다. 재사용성을 높이고 중복을 줄이기. 나중에 나오겠지만 상속과 다형성이 이의 결정체 같은 느낌이기에..

 

이러한 초기화방법들의 실행순서는

기본값 → 명시적 초기화 → 초기화블럭 → 생성자(정적멤버는 해당사항이 없다)

의 순서로 이루어진다.

 

    String name = "윤마치";

    {
        name = "윤만치";
    }

    Member(String name) {
        this.name=name;
    }

    Member() {
        this("윤지영");
    }
    public static void main (String[] args) {
        Member member1 = new Member();
    }

그래서 이런 방식으로 객체를 만들게되면

먼저 String의 기본값인 null이 name에 저장되고, 그 다음 명시적초기화값인 "윤마치"가 name에 저장되고, 초기화 블럭에 있는 "윤만치"가 name에 저장, 마지막으로 생성자를 거치며 최종적으로는 "윤지영"이 Member 객체의 name으로 지정된다.

 

이는 클래스멤버도 마찬가지로 진행되며, 다만 클래스멤버는 생성자를 거치지 않음이 다를 뿐이다.

 

클래스멤버의 초기화는 클래스가 로드될 때, 인스턴스멤버의 초기화는 인스턴스가 형성될 때 일어나게 된다. 한 번 클래스가 로드되면 클래스멤버의 초기화는 일어나지 않는다.

 

이렇게 6장이 끝났다.

6장에서는 OOP를 본격적으로 다루기 전에 클래스, 메서드 등의 내용을 좀 다뤘던 것 같고, 이제 본격적으로 상속이니 다형성이니 하는 것들이 나올 차례인 것 같다.

 

생성자와 초기화블럭도 꽤 재밌고, 유용했다. 처음 자바 배울 때 생성자를 이해하지 못했는데 (이유는 모르겠다.. 근데 처음 배울 때는 모든게 이해가 안될때라.. 지금도 I/O 파트는 이해가 좀 안된다) 이번에 좀 제대로 알아갈 수 있어서 좋다. 헤드퍼스트에는 this나 초기화블럭을 간략하게 다루고 넘어갔는데, 역시 입문서를 한 번 읽었으면 중급도서를 또 한 번 읽어서 그 견문을 넓히고 깊게 해야한다니까

'언어공부 > Java | Kotlin' 카테고리의 다른 글

[CS] 자바의 정석 독서 #10 - 패키지와 접근제어자  (0) 2025.10.02
[CS] 자바의 정석 독서 #9 - 상속  (0) 2025.10.02
[CS] 자바의 정석 독서 #7 - 메서드 오버로딩  (0) 2025.10.01
[CS] 자바의 정석 독서 #6 - 클래스와 메서드  (0) 2025.09.24
[CS] 자바의 정석 독서 #6 - 객체지향 프로그래밍, OOP란 무엇인가?  (0) 2025.09.24
'언어공부/Java | Kotlin' 카테고리의 다른 글
  • [CS] 자바의 정석 독서 #10 - 패키지와 접근제어자
  • [CS] 자바의 정석 독서 #9 - 상속
  • [CS] 자바의 정석 독서 #7 - 메서드 오버로딩
  • [CS] 자바의 정석 독서 #6 - 클래스와 메서드
Radiata
Radiata
개발을 합니다.
  • Radiata
    DDD
    Radiata
  • 전체
    오늘
    어제
    • 분류 전체보기 (211)
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (59)
        • JVM (12)
        • 백엔드 (20)
        • 언어구현 (1)
        • 객체지향 (1)
        • 논리회로 (5)
        • 컴퓨터구조 (9)
        • 데이터베이스 (1)
        • 컴퓨터 네트워크 (10)
      • 언어공부 (64)
        • Java | Kotlin (48)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • [2026] 순수자바로 개발하기 (0)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 놀이터 (0)
      • 에러 수정일지 (2)
      • 고찰 (24)
        • CEOS 23기 회고록 (2)
  • 블로그 메뉴

    • CS
    • 언어공부
    • 개인 프로젝트
    • 팀 프로젝트
    • 알고리즘
    • 고찰
    • 신년사
    • 컬러잇 개발블로그
  • 링크

    • 컬러잇 개발블로그
  • 공지사항

  • 인기 글

  • 태그

    144
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Radiata
[CS] 자바의 정석 독서 #8 - 생성자와 초기화
상단으로

티스토리툴바