자바에서 초기화 블록(init 블록)은 클래스 객체의 인스턴스를 생성할 때 생성자 호출 전에 실행되는 특별한 코드 블록입니다. 두 가지 유형이 있습니다:
public class Example { static { System.out.println("정적 블록"); } { System.out.println("인스턴스 블록"); } public Example() { System.out.println("생성자"); } }
새 객체를 생성할 때 출력되는 내용은:
정적 블록
인스턴스 블록
생성자
초기화 블록은 모든 생성자에 대한 공통 로직이 필요하거나, 변수를 선언하는 데 포함되지 않는 복잡한 초기화가 필요할 때 사용할 가치가 있습니다. 그러나 대부분의 경우 생성자가 더 선호됩니다.
질문: 객체 생성 시 필드, 정적 블록, 인스턴스 블록 및 생성자가 어떤 순서로 초기화되나요?
답변:
이야기
큰 프로젝트에서 초기화에 문제가 발생했습니다: 한 개발자가 생성자에서 공통 로직을 init 블록으로 옮기면서 호출 순서를 고려하지 않았습니다. 그 결과 일부 필드가 로직 실행 전에 올바르게 초기화되지 않아 객체 생성 단계에서 NullPointerException이 발생했습니다.
이야기
추상 클래스에서 큰 init 블록을 재사용하게 되어 다른 클래스들이 초기화 순서를 적절히 재정의하지 못했습니다. 이는 상속 시 예상치 못한 동작과 init 블록 및 생성자 호출 순서와 관련된 버그를 일으켰습니다.
이야기
개발자가 정적 필드가 새로 객체가 생성 될 때마다 재초기화될 수 있다고 가정하고 정적 블록에 자원 정리 로직을 추가했습니다. 이로 인해 자원은 클래스 로드 시 한 번만 정리되었고, 이후 메모리 관리가 "무너지게" 되었습니다. 정적 블록은 단 한 번만 호출되므로 이는 누수와 잘못된 자원 관리로 이어졌습니다.