클래스 로더는 자바 컴파일러가 변환해둔 ByteCode(.class)파일을 동적 로딩합니다.
실행 엔진이 사용할 수 있도록 JVM메모리에 적재하는 역할을 합니다. 로딩 -> 링크 -> 초기화 단계를 진행합니다.
.class 파일을 바탕으로 JVM(메서드 영역)에 로드합니다.
동적로딩을 하기 때문에, static변수나 사용하지 않는 클래스는 로드하지 않습니다. 즉, 한번에 메모리에 모두 로딩하는 게 아니라, 필요한 경우 동적으로 메모리에 로딩을 해주게됩니다.
메서드와 변수 & Class, Interface, Enum 을 구분해서 저장을합니다.
또한, Fully-Quailified Class Nmae형식으로 저장합니다. 로딩이 끝나면 해당 클래스 타입의 객체를 생성하여 메모리 Heap영역에 저장을 합니다.
동적로딩에 대해서 조금 더 알아보면,
public class test {
public static void main(String[] args) {
System.out.println("Main start");
}
}
class Tests {
}
위 코드와 같이 .class 파일에 Temp라는 클래스가 있다고 하더라도, 해당 클래스를 사용하지 않는다면 로드를 하지않습니다. 사용시점에서 로드를 해주게 됩니다.
java -verbose:class test.java 명령어로 로드된 클래스를 확인해봤습니다.

보면, test클래스는 사용하므로 로드 되지만, Tests클래스는 사용하지 않고있기 떄문에 로드되지가 않습니다.
public class test {
public static void main(String[] args) {
System.out.println("Main start");
Tests test = new Tests();
}
}
class Tests {
}

반면 위 코드는 Tests 클래스를 사용했으므로 로드된 것을 확인할 수 있습니다.
그러나, 클래스를 명시적으로 선언(초기화)하지 않아도 로드되는 경우가 있는데, 클래스를 초기화 하지않고 클래스 내부에 static 변수를 호출할 때이다.
public class test {
public static void main(String[] args) {
System.out.println("Main start");
String test = Tests.str;
}
}
class Tests extends P{
static String str = "hello";
}
class P{
}
Tests 클래스에 static String str의 static 변수가 있을때,Tests.str 라는 명령어를 만나게 되면, Tests 클래스도 같이 로드됩니다.
만약 Tests클래스가 P라는 클래스를 상속하고 있다면, 상속하는 P 클래스도 같이 로드됩니다.

위와 같이 test, P, Tests 클래스가 로드된 것을 확인할 수 있습니다.
public class test {
public static void main(String[] args) {
System.out.println("Main start");
new Tests().new In();
}
}
class Tests {
class In{
}
}
이런 식으로 내부 클래스를 상황에서도 내부 클래스를 갖는 외부 클래스를 로드합니다.

클래스 내 멤버를 사용하지만, 클래스를 로드하지 않는 경우도 있습니다.
public class test {
public static void main(String[] args) {
System.out.println("Main start");
String str = Tests.str;
}
}
class Tests {
static final String str = "str";
}
static final String str라는 static final 변수가 있을 때, Tests.str 명령어를 실행하면 Tests 클래스는 로드되지 않습니다.
상수는 JVM의 Constatnt Pool에 따로 저장되어 관리되기 때문입니다.
public class test {
public static void main(String[] args) {
System.out.println("Main start");
Tests.In str = new Tests.In();
}
}
class Tests {
static class In{
}
}
혹은 static class In와 같은 내부 클래스가 있을때, new Tests.In();의 경우 인스턴스를 생성할 때, 외부 클래스가 꼭 필요하지 않으니 외부클래스인 Tests를 로드하지않습니다.
링크는 클래스 파일을 사용하기 위해 검증하는 과정입니다.
링크 단계에서 확보한 메모리 영역에 클래스의 static 변수를 명시된 값으로 할당합니다.