이 멋진 튜토리얼 에서 가져 왔습니다.
자극
C 및 C ++와 같이 정적으로 컴파일 된 프로그래밍 언어로 작성된 응용 프로그램은 시스템 고유의 명령어로 컴파일되어 실행 파일로 저장됩니다. 코드를 실행 가능한 원시 코드로 결합하는 프로세스를 링크라고합니다. 별도로 컴파일 된 코드를 공유 라이브러리 코드와 병합하여 실행 가능한 응용 프로그램을 만듭니다. 이것은 Java와 같이 동적으로 컴파일 된 프로그래밍 언어에서 다릅니다. Java에서 Java 컴파일러에 의해 생성 된 .class 파일은 JVM (Java Virtual Machine)에로드 될 때까지 그대로 유지됩니다. 즉, 링크 프로세스는 런타임시 JVM에 의해 수행됩니다. 클래스는 '필요한'기준으로 JVM에로드됩니다. 로드 된 클래스가 다른 클래스에 종속되면 해당 클래스도로드됩니다.
Java 응용 프로그램이 시작되면 실행할 첫 번째 클래스 (또는 응용 프로그램의 진입 점)는 main ()이라는 공용 정적 void 메서드가있는 클래스입니다. 이 클래스에는 일반적으로 다른 클래스에 대한 참조가 있으며 참조 된 클래스를로드하려는 모든 시도는 클래스 로더에 의해 수행됩니다.
이 재귀 클래스 로딩과 일반적인 클래스 로딩 아이디어를 얻으려면 다음과 같은 간단한 클래스를 고려하십시오.
public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}
로드되는 클래스를 인쇄하도록 -verbose : class 명령 행 옵션을 지정하여이 클래스를 실행하면 다음과 같은 출력이 표시됩니다. 목록이 너무 길어서 여기에 표시 할 수 없기 때문에 이것은 부분 출력 일뿐입니다.
prmpt>java -verbose:class HelloApp
[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]
보다시피, 애플리케이션 클래스 (HelloApp)에 필요한 Java 런타임 클래스가 먼저로드됩니다.
Java 2 플랫폼의 클래스 로더
Java 프로그래밍 언어는 계속해서 애플리케이션 개발자의 삶을 편하게 만들어줍니다. 이는 기본 메커니즘의 구현 세부 사항이 아닌 비즈니스 로직에 집중할 수 있도록하여 생활을 단순화하는 API를 제공함으로써 수행됩니다. 이는 Java 플랫폼의 성숙도를 반영하기 위해 최근 J2SE 1.5에서 J2SE 5.0으로 변경 한 것이 분명합니다.
JDK 1.2부터 JVM에 내장 된 부트 스트랩 클래스 로더는 Java 런타임의 클래스를로드합니다. 이 클래스 로더는 부트 클래스 경로에있는 클래스 만로드하며, 신뢰할 수있는 클래스이기 때문에 신뢰할 수없는 클래스와 마찬가지로 유효성 검사 프로세스가 수행되지 않습니다. JVM에는 부트 스트랩 클래스 로더 외에 표준 확장 API에서 클래스를로드하는 확장 클래스 로더와 일반 클래스 경로 및 애플리케이션 클래스에서 클래스를로드하는 시스템 클래스 로더가 있습니다.
클래스 로더가 두 개 이상 있기 때문에 루트가 부트 스트랩 클래스 로더 인 트리에 표시됩니다. 각 클래스 로더에는 상위 클래스 로더에 대한 참조가 있습니다. 클래스 로더가 클래스를로드하도록 요청되면 항목 자체를로드하기 전에 상위 클래스 로더를 참조합니다. 부모는 차례로 부모와 상담합니다. 따라서 모든 조상 클래스 로더가 현재 클래스 로더와 관련된 클래스를 찾을 수없는 경우에만 발생합니다. 즉, 위임 모델이 사용됩니다.
java.lang.ClassLoader 클래스
는 java.lang.ClassLoader
JVM이 동적으로 클래스를로드 방식을 확장해야하는 응용 프로그램에 의해 서브 클래스화할 수 추상 클래스입니다. java.lang.ClassLoader
새 클래스 로더를 인스턴스화 할 때 생성자 와 하위 클래스의 생성자 를 사용하여 부모를 지정할 수 있습니다. 상위를 명시 적으로 지정하지 않으면 가상 머신의 시스템 클래스 로더가 기본 상위로 지정됩니다. 다시 말해 ClassLoader 클래스는 위임 모델을 사용하여 클래스와 리소스를 검색합니다. 따라서 클래스 로더의 각 인스턴스에는 연관된 상위 클래스 로더가 있으므로 클래스 또는 자원 찾기를 요청하면 클래스 또는 자원 자체를 찾기 전에 태스크가 상위 클래스 로더에 위임됩니다. loadClass()
ClassLoader 의 메소드는 클래스를로드하기 위해 호출 될 때 다음 태스크를 순서대로 수행합니다.
클래스가 이미로드되어 있으면 반환합니다. 그렇지 않으면 새 클래스에 대한 검색을 상위 클래스 로더에 위임합니다. 부모 클래스 로더가 클래스 를 찾지 못하면 loadClass()
메소드 findClass()
를 호출하여 클래스 를 찾아서로드하십시오. finalClass()
현재의 클래스 로더의 클래스에 대한 방법 검색이 클래스는 부모 클래스 로더에 의해 발견되지 않은 경우.
원래 기사에 더 많은 내용이 있으며 자체 네트워크 클래스 로더를 구현하는 방법을 보여줍니다.이 클래스는 왜 (및) 방법에 대한 질문에 대답합니다. API 문서 도 참조하십시오 .