💁♀️ 초기화 블럭(Init Block)이란,
클래스 필드의 초기화만을 담당하는 중괄호({})로 둘러싸인 블럭을 의미
초기화 블럭은 생성자보다 먼저 호출되며, static 키워드의 유무에 따라 구분
- 인스턴스 초기화 블럭
- 클래스 초기화 블럭
- 인스턴스 변수
: JVM기본값 > 명시적 초기값 > 인스턴스 초기화 블럭 > 생성자
- 클래스 변수
: JVM기본값 > 명시적 초기값 > 정적 초기화 블럭 > 인스턴스 초기화 블럭 > 생성자
public class Product {
>>> 필드를 초기화하지않으면 JVM이 정한 기본 값으로 객체가 생성
// private String name;
// private int price;
// private static String brand;
// 명시적 초기화
private String name = "갤럭시";
private int price = 1000000;
private static String brand = "삼송";
// 초기화 블럭
// 인스턴스 초기화 블럭
{
name = "사이언";
price = 600000;
>>> 인스턴스 초기화 블럭이 동작하는 시점에는 이미 초기화가 진행 된 정적 필드에
>>> 인스턴스 초기화 블럭에서 대입한 값으로 덮어쓰게 되는 것
brand = "사과";
>>> 인스턴트 초기화 블럭으로 static 초기화 블럭을 덮기 때문에 이것이 실행 가능한 것
System.out.println("인스턴스 초기화 블럭 동작함...");
}
// static 초기화 블럭
static {
brand = "헬지";
>>> static 초기화 블럭에서는 non-static 필드를 초기화 하지 못 함
>>> 정적 초기화 블럭의 동작 시점(프로그램 실행 시)에는 인스턴스가 아무것도 존재하지 않기 때문에
>>> 존재하지 않는 인스턴스 변수에 초기화 하는 것은 시기상 불가능
// name = "아이뽕";
// price = 2000000;
System.out.println("static 초기화 블럭 동작함...");
}
// 생성자
// 기본 생성자
public Product() {
System.out.println("기본 생성자 호출됨...");
}
// 매개변수가 있는 생성자
public Product(String name, int price, String brand) {
this.name = name;
this.price = price;
Product.brand = brand; >>> static 이므로 클래스명.필드명
System.out.println("매개변수 생성자 호출됨...");
}
public String getInformation() {
return "Product [name = " + this.name + ", price = " + this.price + ", brand = " + Product.brand + "]";
}
}
public class Application {
public static void main(String[] args) {
// 초기화 블럭과 초기화 순서
Product product = new Product();
System.out.println(product.getInformation());
Product product2 = new Product("대륙폰", 300000, "샤우미");
System.out.println(product2.getInformation());
}
}
💻 Mini Console
static 초기화 블럭 동작함...
인스턴스 초기화 블럭 동작함...
기본 생성자 호출됨...
Product [name = 사이언, price = 600000, brand = 사과]
인스턴스 초기화 블럭 동작함...
매개변수 생성자 호출됨...
Product [name = 대륙폰, price = 300000, brand = 샤우미]
📌 Ref.
* 모든 변수(인스턴스 변수, 클래스 변수)의 초기화 순서 마지막은 '생성자'
따라서, product2를 호출했을 때, 매개변수 생성자가 인스턴스 초기화 블럭의 값을 덮어쓴 것