Programming

Class.forName () 대 ClassLoader.loadClass ()-동적 로딩에 사용할 것은 무엇입니까?

procodes 2020. 8. 23. 10:12
반응형

Class.forName () 대 ClassLoader.loadClass ()-동적 로딩에 사용할 것은 무엇입니까? [복제]


이 질문에 이미 답변이 있습니다.

클래스를 동적으로로드 할 때 사용하는 것이 적절한시기

Class.forName("SomeClass");

그리고 언제 사용해야합니까

ClassLoader.getSystemClassLoader().loadClass("SomeClass");

아니면 두 가지 방법으로 동일한 작업을 수행합니까?


그들은 아주 다릅니다!

에 대한 설명서에 명시된대로 Class.forName(String),

주어진 문자열 이름을 가진 클래스 또는 인터페이스와 관련된 Class 객체를 반환합니다. 이 메서드를 호출하는 것은 다음과 같습니다.Class.forName(className, true, currentLoader)

( true여기서는 클래스를 초기화 하시겠습니까? )

반면에 ClassLoader.loadClass(String):

이 메서드를 호출하는 것은을 호출하는 것과 같습니다 loadClass(name, false).

(여기서 부울은 초기화와 관련이 없습니다.하지만 loadClass (String, boolean) 문서를 확인하면 클래스를 초기화하는 것이 아니라로드하는 것이 전부임을 알 수 있습니다).

첫 번째 항목 ( Class.forName("SomeClass");)은 다음을 수행합니다.

  • 이 코드를 호출하는 클래스를로드 한 클래스 로더를 사용하십시오.
  • 클래스 초기화 (즉, 모든 정적 초기화 프로그램이 실행 됨)

다른 ( ClassLoader.getSystemClassLoader().loadClass("SomeClass");)은 다음을 수행합니다.

  • "시스템"클래스 로더 사용 ( 재정의 가능 )
  • 클래스를 초기화하지 마십시오 (예 : JDBC 드라이버를로드하는 데 사용하면 등록되지 않고 JDBC를 사용할 수 없습니다!).

Tomcat과 같은 컨테이너에서 실행될 웹 애플리케이션을 코딩한다고 가정합니다. Tomcat이하는 일은 각 웹 응용 프로그램에 대한 클래스 로더를 만드는 것입니다 (나중에 웹 응용 프로그램을 언로드하고 메모리를 해제 할 수 있도록이 작업을 수행하려면 전용 클래스 로더가 필요합니다!). 이 상황에서 두 호출 모두 상당히 다른 결과가 생성된다는 것을 알 수 있습니다!

클래스 로딩 및 초기화에 대한 더 자세한 (그리고 권위있는) 정보 는 Java 언어 사양의 최신 (3rd) 에디션의 섹션 12.212.4확인하십시오 .


Class.forName() 호출자의 클래스 로더를 사용하고 클래스를 초기화합니다 (정적 초기화 프로그램 실행 등).

loadClassA는 ClassLoader방법, 그래서 명시 적으로 제공하는 로더를 사용하고 (처음 사용)로 지연 클래스를 초기화한다.

또한를 사용 하는 Class.forName () 이 있습니다 ClassLoader.


그들은 기본적으로 같은 일을하고 있습니다. 사용되는 ClassLoader는 다를 수 있습니다. Class.forName은 this.getClass (). getClassLoader ()에서 얻은 ClassLoader를 사용하는 반면 다른 코드는 시스템 클래스 로더를 사용하도록 지정합니다.

대부분의 응용 프로그램에서 이것은 동일한 클래스 로더이지만 J2EE 응용 프로그램이나 애플릿과 같은 더 복잡한 환경에서는 그렇지 않을 수 있습니다.


ClassLoader는 추상 클래스이지만 응용 프로그램은 항상 클래스 로더에 의해로드되며 네트워크 클래스 로더 또는 기타 소스와 같은 사용자 정의 클래스 로더가있을 수 있습니다.

반면에 클래스 자체는 클래스와 인터페이스를 나타내며 클래스 클래스에는 애플리케이션이 기본적으로 실행되는 현재 클래스 로더를 사용하여 클래스를로드하는 forName 함수가 있습니다.

다음은 호출하는 클래스 로더를 호출하는 Class.forName의 소스입니다.

public static Class<?> forName(String className)
            throws ClassNotFoundException {
    return forName0(className, true, ClassLoader.getCallerClassLoader());
}

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#forName(java.lang.String )

힌트 : 원시 클래스 로더 http://docs.oracle.com/javase/1.4.2/docs/guide/security/spec/security-spec.doc5.html


  • Class.forName()클래스를로드하고 초기화합니다. 클래스 로더 하위 시스템에서는로드, 링크 및 초기화 단계의 세 단계를 모두 실행합니다.

  • ClassLoader.loadClass()동작은 클래스가 처음 사용될 때까지 초기화를 지연시킵니다. 클래스 로더 하위 시스템에서는로드 및 링크 단계의 두 단계 만 실행합니다.

예를 들면 :

class MyClass {
    static {
        System.out.println("static block in MyClass");
    }
}

public class TestCase1 {
    public static void main(String... args) throws Throwable {
        Class.forName("A");
    }
} //The above TestCase1 produce output: static block in MyClass

public class TestCase2 {
    public static void main(String... args) throws Throwable {
        ClassLoader.getSystemClassLoader().loadClass("MyClass");
    }
} //The above TestCase2 not produce any output

나는 자바에서 클래스 로딩을 좋아합니다 ...

실제로 응용 프로그램이 실행되는 컨텍스트에 따라 다릅니다. 명령 줄 프로그램이 아닌 웹 컨텍스트에서 사용하면 다른 결과를 얻을 수 있습니다.

또한 ClassPath의 모양과 예상했던 작업에 따라 문제가 발생했습니다.

JavaWorld 기사는 이에 대한 좋은 거래를 설명합니다.

참고 URL : https://stackoverflow.com/questions/8100376/class-forname-vs-classloader-loadclass-which-to-use-for-dynamic-loading

반응형