프로그래밍/JAVA

[ JAVA ] 변수의 초기화란? 변수의 초기화 방법

리신 2022. 10. 5. 20:48
반응형

변수의 초기화란?

변수를 선언하고 처음으로 값을 저장하는 것을 '변수의 초기화'라고 한다.

변수의 초기화는 경우에 따라서 필수적이기도 하고 선택적이기도 하다!

하지만 가능하면 선언과 동시에 적절한 값으로 초기화하는 것이 바람직하다!

 

✅ 참고

멤버 변수 초기화 : 초기화를 하지 않아도 자동적으로 변수의 자료형의 기본값으로 초기화가 이루어짐.
지역변수 초기화 : 사용하기 전에 반드시 초기화해야 한다.

 

💎예제💎

class InitTest {
    int x;    // 인스턴스 변수
    int y = x; // 인스턴스 변수
    
    void method1 (){
       int i;
       int j = i;
    }
}

위와 같이 코드를 작성하면 에러가 발생한다.

 

[위 코드 내용 정리]

x, y는 인스턴스 변수이고, i, j는 지역변수이다.

그중 x와 i는 선언만 하고 초기화를 하지 않았다.

그리고 y를 초기화하는 데 x를 사용하였고, j를 초기화하는 데 사용하였다.

 

인스턴스 변수 x는 초기화를 해주지 않아도 자동적으로 int형의 기본값이 0으로 초기화되므로, 'int y = x;'와 같이 할 수 있다.

x의 값이 0이므로 y 역시 0이 저장된다.

 

method1()의 지역변수 i는 자동적으로 초기화되지 않으므로, 초기화되지 않은 상태에서 변수 j를 초기화하는 데 사용될 수 없다.

 

멤버 변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택적이지만, 지역변수의 초기화는 필수적이다.

 

✅ 멤버 변수의 초기화 방법에는 3가지가 있다.

1. 명시적 초기화
2. 생성자
3. 초기화 블록
     - 인스턴스 초기화 블록 : 인스턴스 변수를 초기화하는 데 사용.
     - 클래스 초기화 블록     : 클래스 변수를 초기화하는 데 사용.

 

아래에서 자세히 알아보자!


1. 명시적 초기화

변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다.

가장 기본적이면서도 간단한 초기화 방법이므로 여러 초기화 방법 중에서 가장 우선적으로 고려되어야 한다!

 

💎예시💎

class Car {
    int door = 4;   /// 기본형 변수의 초기화
    Engine e = new Engine();   /// 참조형 변수의 초기화
}

 

명시적 초기화가 간단하고 명료하긴 하지만,

보다 복잡한 초기화 작업이 필요할 때는 '초기화 블록' 또는 생성자를 사용해야 한다.

 

 


2. 초기화 블록

초기화 블록에는 '클래스 초기화 블록'과 '인스턴스 초기화 블록' 두 가지 종류가 있다.

클래스 초기화 블록        클래스 변수의 복잡한 초기화에 사용된다
인스턴스 초기화 블록    인스턴스 변수의 복잡한 초기화에 사용된다.

 

💎예시💎

class InitBlock {
   static {/* 클래스 초기화블럭 입니다. */}
   {/* 인스턴스 초기화블럭 입니다. */}
}

위 코드와 같이 사용하면 된다!.

 

✅ 초기화 블록 작성

인스턴스 초기화 블록 : 단순히 클래스 내에 블록 {} 만들고 그 안에 코드 작성

클래스 초기화 블록 : 인스턴스 초기화 블록 앞에 단순히 static을 덧붙이면 된다.

 

* 초기화 블록 내에는 메서드 내에서와 같이 조건문, 반복문, 예외처리 구문 등 자유롭게 사용 가능

 

✅ 기억하자!

클래스 초기화 블록은 클래스가 메모리에 처음 로딩될 때 한 번만 수행된다.
인스턴스 초기화 블록은 생성자와 같이 인스턴스를 생성할 때마다 수행된다.

* 생성자 보다 인스턴스 초기화 블록이 먼저 수행된다.
* 클래스가 처음 로딩될 때 클래스 변수들이 자동적으로 메모리에 만들어지고, 곧바로 클래스 초기화 블록이 클래스 변수들을 초기화하게 되는 것임.

 

그럼 어떨 때 사용하면 좋을까❗❔

인스턴스 초기화 블록은 모든 생성자에서 공통으로 수행돼야 하는 코드를 넣는 데 사용한다.

따라서 코드 중복을 제거할 수 있다.

 

예제로 알아보자

💎예제💎

Car () {
    count++;
    serialNo = count;
    color = "White";
    gearType = "Auto";
}

Car (String color, String gearType) {
    count++;
    serialNo = count;
    this.color = color;
    this.gearType = gearType;
}

위 예제를 보면 두 개의 생성자 안에 공통으로 수행되어야 하는 문장들이 있다.

이때 그 문장들을 모든 생성자마다 써주기보다는 아래와 같이 인스턴스 블록에 넣어주면 코드가 보다 간결해진다.

 

{ /* 인스턴스 초기화 */
    count++;
    serialNo = count;
}

Car () {
    color = "White";
    gearType = "Auto";
}

Car (String color, String gearType) {
    this.color = color;
    this.gearType = gearType;
}

이처럼 코드의 중복을 제거하는 것은 코드의 신뢰성을 높여 주고, 오류의 발생 가능성을 줄여준다는 장점이 있다.

 

 


3. 멤버 변수의 초기화 시기와 순서

위에서 멤버 변수를 초기화하는 방법에 대해서 알아봤다.

다음은 초기화가 수행되는 시기와 순서에 대해서 정리해보자!!

 

✅ 정리

클래스 변수의 초기화 시점          클래스가 처음 로딩될 때 단 한번 초기화된다.
인스턴스 변수의 초기화 시점      인스턴스가 생성될 때마다 각 인스턴스 별로 초기화가 이루어진다.

클래스 변수의 초기화 순서          기본값 명시적 초기화 →  클래스 초기화 블록
인스턴스 변수의 초기화 순서      기본값 →  명시적 초기화 →  인스턴스 초기화 블록 → 생성자

 

✅ 참고

클래스의 로딩 시기는 JVM의 종류에 따라 좀 다를 수 있는데,
클래스가 필요할 때 바로 메모리에 로딩하도록 설계가 되어있는 것도 있고,
실행 효율을 높이기 위해서 사용될 클래스들을 프로그램이 시작될 때 미리 로딩하도록 되어있는 것도 있다.

잘 이해가 되지 않을 수 있으니 아래 예시를 통해 알아보자.

 

💎예시💎

class InitTest{
    /* 명시적 초기화*/
    static int cv = 1;
    int iv = 1;
    
    static {   cv =2;   } /* 클래스 초기화 블럭*/
    {   iv = 2   }   /* 인스턴스 초기화 블럭 */
    
    initTest () { /* 생성자 */
       itv = 3;
    }
}

위 코드의 inittest클래스는 클래스 변수(cv)와 인스턴스 변수(iv)를 각각 하나씩 가지고 있다.

'new InitTest();'와 같이 하여 인스턴스를 생성했을 때, cv와 iv가 초기화되어가는 과정을 단계별로 보자

 

- 클래스 변수 초기화 (1 ~ 3)   : 클래스가 처음 메모리에 로딩될 때 차례대로 수행됨.

- 인스턴스 변수 초기화 (4~7) : 인스턴스를 생성할 때 차례대로 수행됨.

 

* 클래스변수는 항상 인스턴스 변수보다 항상 먼저 생성되고 초기화된다.

 

✅ 과정

1. cv가 메모리(method area)에 생성되고, cv에는 int형의 기본값이 0이 cv에 저장된다.

2. 그다음에는 명시적 초기화(int cv = 1)에 의해서 cv에 1이 저장된다.

3. 마지막으로 크래스 초기화 블록 (cv = 2 )이 수행되어 cv에는 2가 저장된다.

4. Inittest클래스의 인스턴스가 생성되면서 iv가 메모리(heap)에 존재하게 된다.

     iv 역시 int형 변수미로 기본값 0이 저장된다.

5. 명시적 초기화에 의해서 iv에 1이 저장되고

6. 인스턴스 초기화 블록이 수행되어 iv에 2가 저장된다.

7. 마지막으로 생성자가 수행되어 iv에는 3이 저장된다. 

 

 

 

* 참고: 자바의 정석

 

 

 

 

반응형