얼마 전, Enum을 사용하다 순환참조 에러를 겪은 일이 있었다.
해당 과정에서 Java의 동적로딩에 알게 되었고,
깊숙하게 숨어있던 Class Loader에 대해 알아보려 한다.
💡 자바는 동적로딩을 지원한다
프로그램 실행 시에 모든 클래스가 로드되는 것이 아닌,
해당 클래스가 필요한 시점에 클래스를 로드한다.
JAVA는 JVM을 통해서 실행된다.
JVM은 기본적으로 Garbage Collector, Class Loader, Execution Engine, Runtime Data Area로 이루어져 있고, ClassLoader라는 녀석이 동적로딩을 가능케 해준다
JVM에 대해서는 다음에 알아보고
오늘은 ClassLoader에 대해 알아보자
Java를 통해 개발을 하게 되면 .java 라는 파일이 생성된다.
해당 파일은 컴파일러에 의해 컴퓨터가 읽을 수 있는 바이트 코드로 변환하게 되고, 그 파일이 바로 .class이다.
이렇게 컴파일 된 바이트코드를 Class Loader가 메모리영역으로 옮겨주게 된다.
public class Main {
public static void main(String[] args) {
System.out.println("프로그램을 시작합니다");
System.out.println("프로그램이 시작됐어요");
A a = new A();
System.out.println("프로그램이 동작 중이에요");
System.out.println("프로그램을 종료합니다");
}
}
class A {
static {
System.out.println("안녕하세요 A의 정적 블록이에요");
}
{
System.out.println("안녕하세요 A의 인스턴스 블록이에요");
}
public A () {
System.out.println("안녕하세요 A의 생성자에요");
}
}
class B {
static {
System.out.println("안녕하세요 B의 정적 블록이에요");
}
{
System.out.println("안녕하세요 B의 인스턴스 블록이에요");
}
public B () {
System.out.println("안녕하세요 B의 생성자에요");
}
}
/**
* Output
* 프로그램을 시작합니다
* 프로그램이 시작됐어요
* 안녕하세요 A의 정적 블록이에요
* 안녕하세요 A의 인스턴스 블록이에요
* 안녕하세요 A의 생성자에요
* 프로그램이 동작 중이에요
* 프로그램을 종료합니다
/
위 코드에서 바이트코드를 필요로 하는 부분을 만난 순간은 A생성자에 접근하는 순간이다. 프로그램의 시작을 알리는 출력문들을 통해 A에 접근할 때까지 로드되지 않는 모습을 볼 수 있다. 또한, B에 접근을 하지 않았기에 클래스 B의 로드는 이루어지지 않은 것으로 보인다.