2010-04-15 3 views
11

ClassLoader에서 loadClass()을 호출 할 때 클래스가로드되었는지 처음 확인하면 ClassLoader이 수행합니까? 아니면이 수표를 부모 ClassLoader에 즉시 위임합니까?Java ClassLoader 위임 모델?

자바 API는 말한다 :

클래스 또는 자원을 찾아 요청

는, 클래스 로더 인스턴스 클래스를 찾거나 자신을 자원하기 전에 부모 클래스 로더에 클래스 또는 자원의 검색을 위임합니다.

그러나 말한다 액션의 책 자바 반사의 클래스 로더에 대한 특정 장있다 :

클래스 로더는 클래스가 클래스 로더 already.If로드되어 있는지 확인하는 findLoadedClass를 호출은 로드 된 클래스를 찾지 못하면 상위 클래스 로더에서 loadClass를 호출합니다.

어느 쪽이 맞습니까?

답변

13

적절한 클래스 로더의 구현은 것입니다 : 클래스가 이미로드 된

  1. 확인합니다.
  2. 일반적으로 상위 클래스 로더에게 클래스를로드하도록 요청하십시오.
  3. 클래스 경로에서 클래스를 찾으려고 시도합니다.

ClassLoader.loadClass의 기본 구현은 같은 :

protected synchronized Class<?> loadClass(String name, boolean resolve) { 
    // First, check if this class loader has directly defined the class or if the 
    // JVM has initiated the class load with this class loader. 
    Class<?> result = findLoadedClass(name); 
    if (result == null) { 
    try { 
     // Next, delegate to the parent. 
     result = getParent().loadClass(name); 
    } catch (ClassNotFoundException ex) { 
     // Finally, search locally if the parent could not find the class. 
     result = findClass(ex); 
    } 
    } 
    // As a remnant of J2SE 1.0.2, link the class if a subclass of the class 
    // loader class requested it (the JVM never calls the method, 
    // loadClass(String) passes false, and the protected access modifier prevents 
    // callers from passing true). 
    if (resolve) { 
    resolveClass(result); 
    } 
    return result; 
} 

일부 클래스 로더 구현 것, 예를 들어 다른 비 부모 클래스 로더 (은 OSGi, 클래스 로더의 그래프에 위임하는 위임 패키지에 의존), 일부 클래스 로더 구현은 위임하기 전에 로컬 클래스 경로에서 클래스를 찾습니다.

+0

사실이 아닙니다. http://stackoverflow.com/a/245038/632951에 설명 된대로 많은 클래스로드 모델이 있습니다. "적절하다"고 말하는 것은 모델 중 하나 일뿐입니다. 다른 모델은 실제로 이러한 방식으로 구현되지 않습니다. – Pacerier

+0

맞습니다. 답은 너무 규범 적입니다. 느슨한 언어를 추가하고 클래스 로더가 다른 시나리오를 추가했습니다. 의견을 보내 주셔서 감사합니다. –

1

이것은 기본적으로 작동하는 방식입니다. 당신은 Foo() 메모리/파마 세대에서의 비트 즉로드 된 경우 클래스 로더가 결정한다이 시점에서

Foo f = new Foo(); 

을 입력합니다. 로드 된 경우 사용하십시오. 그렇지 않으면 상위 클래스 로더에 위임하여 클래스 해결을 시도하십시오. 이 클래스의 비트는 디스크에서 읽은 다음 메모리로로드됩니다. 다음 new Foo()에서 클래스는 이제 memory/loaded에 있습니다.

2

자바 API가 정확합니다.

클래스 또는 자원을 찾기 위해 요청하면 ClassLoader 인스턴스 것이다 위임 클래스 또는 자원 자체를 찾기 위해 시도하기 전에 부모 클래스 로더 의 클래스 또는 자원에 대한 검색. Java Classloading Mechanism에서

-

클래스, 클래스 로더 최초의 "대표"클래스 자체를 찾기 위해 시도하기 전에 부모 클래스 로더 클래스의 검색을로드.

+0

혼란 스럽네요 - 이것은 @bkail에서 주어진 대답이 잘못되었음을 의미합니까? –

0

Sri의 답변에 동의하면 항상 부모에게 위임되며 API는 올바른 것입니다. 클래스 로딩을 사용하고 있다면,이 작업은 약간의 어려움을 겪고 나면 효과를 얻을 수 있습니다. jvm을 최소 classpath로 시작한 다음 사용자 정의 클래스 로더를 사용하여 모든 클래스를로드하는 것이 가장 쉬운 방법은 URLClassloader 또는 URLClassloader를 래핑하는 복합 객체를 사용하여 어떤 클래스가로드되었는지 추적 할 수 있고 언제.

C와 D가 동일한 클래스 로더 - 상위 - 하위 계층의 일부가 아닌 경우 클래스 로더 C! = 클래스 A가로드 한 클래스 A가 클래스 C에서로드됨을 유의해야합니다.

2

두 문은 서로 상호 배타적이지 않습니다. ClassLoader가 이전에 Class를 찾지 못한 경우, Class는 현재의 ClassLoader의로드 된 클래스 세트에만 존재합니다. 그래서,

(설명 외부 데이터) 클래스 또는 자원을 찾기 위해 요청

클래스 로더 인스턴스를 것이다 대표 (설명 외부 데이터) 클래스 또는 상위 클래스에 자원에 대한 검색 클래스 또는 리소스 자체를 (설명하는 외부 데이터) 찾기 시도하기 전에 로더 .

그것의 부모 클래스를 찾을 수 없습니다 알고 있다면 그러나이

0

해야 하나 문제가있다 (이전에 클래스를로드 그것을 같이) 할 수 단락되는 것을 방지하지 않는 이 문맥에서 언급했다. 이 API의 문서는 말한다 :

방법과 클래스 로더 수도 참조 다른 클래스에 의해 생성 객체의 생성자. 참조 된 클래스 ( )를 확인하기 위해 Java 가상 컴퓨터는 클래스를 처음 만들었던 클래스 로더의 loadClass 메서드를 호출합니다.

참조하는 클래스의 네트워크가 동일한 클래스 로더에 의해로드된다는 것을 의미합니다.

+0

그 뜻이 아닙니다 : "Java 가상 머신은 원래 클래스를 생성 한 클래스 로더의 loadClass 메소드를 호출합니다."그러면 즉시 부모 클래스 로더에 위임됩니까? –