티스토리 뷰

JAVA

[JAVA] 변수의 초기화

코헴 2019. 5. 22. 22:25

변수의 초기화

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

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

class InitTest {
  int x;
  int y = x; //문제 없음

  void method() {
    int i;
    int j = i; // 컴파일 에러: 지역변수를 초기화하지 않고 사용함
  }
}

멤버 변수의 초기화 방법

  • 명시적 초기화(explicit initialization)
  • 생성자(constructor)
  • 초기화 블럭(initialization block)
    • 인스턴스 초기화 블럭 : 인스턴스 변수를 초기화 하는데 사용
    • 클래스 초기화 블럭 : 클래스 변수를 초기화하는데 사용

명시적 초기화 (explicit initialization)

변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다. 가장 기본적이고 간단한 초기화 방법이며, 여러 초기화 방법 중 가장 우선적으로 고려되어야 한다.

class Car {
    int door = 4;
  Engine e = new Engine();

  //...
}

명시적 초기화가 간단하고 명료하긴 하지만 보다 복잡한 초기화 작업이 필요할 때는 '초기화 블럭(initialization block)' 또는 생성자를 사용해야 한다.

초기화 블럭(initialization block)

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

인스턴스 초기화 블럭

초기화 블럭을 작성하려면 인스턴스 초기화 블럭은 단순히 클래스 내에 블럭 { } 을 만들고 그 안에 코드를 작성하기만 하면 된다. 그리고 클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 단순히 static을 덧붙이기만 하면 된다.

초기화 블럭 내에는 메소드 내에서와 같이 조건문, 반복문, 예외처리구문 등을 자유롭게 사용할 수 있으므로 초기화 작업이 복잡하여 명시적 초기화만으로는 부족한 경우 초기화 블럭을 사용한다.

class InitBlock {
  static { /* 클래스 초기화 블럭 */ }

  { /* 인스턴스 초기화 블럭 */ }

}

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

그리고 생성자 보다 인스턴스 초기화 블럭이 먼저 수행된다는 점이 중요하다

인스턴스변수의 초기화는 주로 생성자를 사용하기 때문에 인스턴스 초기화 블럭은 잘 사용되지 않는다. 대신 클래스의 모든 생성자에서 공통적으로 수행되어져야 하는 코드가 있는 경우 생성자에 넣지 않고 인스턴스 초기화 블럭에 넣어두면 코드의 중복을 줄일 수 있어서 좋다.

예를들면 클래스의 모든 생성자에 공통적으로 수행되어야 하는 문장들이 있을 때, 이 문장들을 각 생성자마다 써주기 보다 아래와 같이 인스턴스 블럭을 이용하면 코드가 보다 간결하고 유지보수하기 쉬워진다.

Car() {
  System.out.println("Car 인스턴스가 생성되었습니다.");
  color = "White";
  gearType = "Auto";
}

Car() {
  System.out.println("Car 인스턴스가 생성되었습니다.");
  this.color = color;
  this.gearType = gearType;
}

// 이러한 코드가 이렇게 된다!

{ System.out.println("Car 인스턴스가 생성되었습니다."); } //인스턴스 블럭
Car() {
  color = "White";
  gearType = "Auto";
}

Car() {
  this.color = color;
  this.gearType = gearType;
}
클래스 초기화 블럭
class BlockTest {
  static {
    System.out.println("class initialize block");
  }

  {
    System.out.println("instance initialize block");
  }

  public BlockTest() {
    System.out.println("constructor");
  }

  public static void main(String[] args) {
      System.out.println("first block test");
    BlockTest bt = new BlockTest();

  }
  /* 결과
  class initialize block
  first block test
  instance initialize block
  constructor
  */
}
  • 클래스 초기화 블럭 -> 인스턴스 초기화 블럭 -> 생성자 순으로 진행

위 실행 결과에서도 알수 있듯이 초기화 블럭은 처음 메모리에 로딩 되는 시점에 실행된다

이러한 초기화 블럭은 배열이나 예외처리가 필요한 초기화에서 사용된다. 다음은 그 예시이다.

class StaticBlockTest {
  static int[] arr = new int[10];

  static {
    for(int i=0;i<arr.length;i++) {
      arr[i] = (int)(Math.random() * 10) + 1;
    }
  }

    public static void main(String args[]) {
      for(int i=0;i<arr.length;i++) {
        System.out.println("arr["+i+"] : " + arr[i]);
      }
    }
}

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

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

클래스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
인스턴스변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자

프로그램 실행 도중 클래스에 대한 정보가 요구되어 질 때 클래스는 메모리에 로딩된다. 예를 들면 클래스 멤버를 사용했을 때, 인스턴스를 생성할 때 등이 이에 해당한다.

하지만 해당 클래스가 이미 메모리에 로딩되어 있다면, 또다시 로딩하지 않는다. 물론 초기화도 다시 수행되지 않는다.

참고 : Java의 정석(남궁 성 지음)

'JAVA' 카테고리의 다른 글

[JAVA] 생성자  (0) 2019.05.22
[JAVA] 변수와 메소드  (0) 2019.05.22
[JAVA]JVM구조 이해하기  (0) 2019.01.15
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함