Whiteship's Note

Class.forName()와 ClassLoader.loadClass() 차이점

Java : 2010.03.09 18:04


http://www.javaworld.com/javaworld/javaqa/2003-03/01-qa-0314-forname.html?page=1

일단 Class.forName() 메서드는 인자가 한 개 짜리인 것과 세 개 짜리인 것이 있습니다.

static Class<?>     forName(String className)
          Returns the Class object associated with the class or interface with the given string name.

static Class<?>     forName(String name, boolean initialize, ClassLoader loader)
          Returns the Class object associated with the class or interface with the given string name, using the given class loader.

1. 클래스를 로딩할 때 사용하는 클래스로더 차이

인자가 한개 짜리인 forName(String) 메서드는 클래스를 로딩할 때 사용하는 클래스로더가 저 코드를 실행하는 클래스로더가 됩니다. 하지만 ClassLoader.loadClass()를 사용하면 당연히 자기 자신을 사용해서 클래스 로딩을 실행하게 되죠. (그렇다고 해서 반드시 해당 클래스로더가 읽어온다는 보장은 없죠. 그 부모가 읽어올 수도 있고 클래스 패스에 없을 수도 있고 암튼 여기서 로딩한다는 건 로딩을 시도한다고 보시기 바랍니다.)

하지만 Class.forName(String, boolean, ClassLoader)를 사용하면 클래스 로더를 지정해 줄 수 있습니다.

2. 초기화

Class.forName(String) 메서드를 사용하면 곧바로 클래스의 static 초기화 블럭과 static 멤버 변수의 값을 초기화 합니다. 하지만 ClassLoader.loadClass()를 사용하면 해당 클래스를 처음으로 사용하기 전까지 초기화가 지연됩니다.

이것 역시 Class.forName(String, boolean, ClassLoader)의 두번째 인자값을 이용하여 조절할 수 있습니다.

- 클래스 초기화 에러

만약 Class.forName(String)을 사용해서 로딩할 때 static 영역에서 에러가 난다면 해당 클래스는 다시 로딩할 수가 없습니다. 특정 클래스로더가 일단 로딩한 클래스는 다시 로딩할 수가 없죠. 그래서 NoClassDefinitionFound 에러가 날 수도 있습니다.

이때는 해당 클래스로더 인스턴스를 버리고 새로 만들어야 하는데 그럴 때를 대비해 인자 세개짜리 forName을 쓰라는군요.

결국 forName()으로 클래스를 로딩할 떄는 별 개의 클래스로더를 쓰라는건데... 흠.. 그렇게 단순해 보이지가 않는데;; 머 클래스로더를 지정해 둔다고 해봤자. 보통 App CL로 읽어올테고 그럼 App CL 인스턴스를 버리라고?? 에이;; 그건 좀..

forName으로 읽어올 클래스를 클래스패스를 가지고 있으면서 parent로 위임하지도 않는 CL을 이용해서 forName으로 읽은 경우라면 뭐 괜찮을지도.. 어쨋거나 직접 통제가 가능한 클래스로더를 사용해야 겠군요.


top




: 1 : ··· : 164 : 165 : 166 : 167 : 168 : 169 : 170 : 171 : 172 : ··· : 2638 :