2013-03-09 3 views

답변

9

원하는대로 할 수있는 100 % 신뢰할 수있는 방법은 없습니다. 이유는 Java에서 클래스 로딩이 작동하는 방식 때문입니다.

Java의 클래스는 "주문형"으로로드됩니다. 클래스가 코드에서 처음 참조 될 때 (정적 또는 동적으로) JVM은 현재 클래스 로더를 사용하여로드하려고 시도합니다. ClassLoader에는로드 할 수있는 모든 클래스를 제공하는 메서드가 없으므로 클래스를 반복 할 수 없습니다.

일부 신뢰할 수없는 해결 방법이 있습니다. 예를 들어, ClassLoader가 특정 디렉토리 또는 특정 JAR 파일 내부에서 클래스를로드하는 경우, 파일 시스템과 관련된 클래스를 사용하여 ".class"파일을 사용할 수 있는지 알아낼 수 있습니다. (모든 ClassLoader 매직을하지 않는 한) 클래스를 언로드 할 수 없다는 것을 명심하십시오.) 그리고 리플렉션을 사용하여 클래스를 필터링하는 데 시간을 요하며 많은 PermGen을 소비합니다. 인터페이스.

이 해결 방법의 문제점은 배포를 변경 한 경우 작동하지 않을 가능성이 높습니다. 예를 들어 JAR 파일 배포를 시작한 다음 나중에 WAR 파일을 처리 할 서블릿 컨테이너를 사용하기로 결정하면 코드가 더 이상 작동하지 않을 수 있습니다.

이 접근 방식을 실제로 사용하려는 경우 유용한 Reflections 프로젝트가 있습니다.

내가 구현 한 가장 신뢰할 수있는 방법은 Annotation Processor을 사용하는 것입니다. 주석을 작성하고 인터페이스에 주석을 추가하며 컴파일 타임에 컴파일러가 실행하는 코드를 작성하여 인터페이스를 구현하는 클래스를 수집하고 해당 이름을 리소스 파일에 저장합니다. 그런 다음 해당 파일을 읽는 메서드로 클래스를 작성하고 해당 리소스 파일에 나열된 각 클래스 이름에 대한 Class 객체를 제공합니다.

이 방법의 문제점은 내 빌드 프로세스에서 컴파일 된 클래스 만 나열된다는 것입니다. 즉, 인터페이스가있는 라이브러리를 게시하고 다른 사용자가 인터페이스를 구현할 것을 기대하는 경우이 방법은 유용하지 않습니다. 코드는 다른 사람들의 프로젝트에서 클래스에 대해 결코 알 수 없으므로). 이 솔루션이 나에게 도움이된다면,이 솔루션은 완벽하게 작동합니다. 실행 가능한 jar에 WAR (exploded 또는 not) 배포가있는 Servlet Container에서 사용할 수 있습니다. 그것은 항상 효과가있을 것입니다.

+0

정말요? 내 IDE는 괜찮아요 ... –

+0

@BrianRoach, 오, 정말요? 이제 IDE에 클래스 나열을 요청한 다음 목록에서 CTRL + C를 누르고 코드에서 Ctrl + V를 누르고 (새 클래스를 추가 할 때마다 수동으로 업데이트) IDE가 완전히 알고 있다는 사실을 묻습니다 실행중인 코드에는 쓸모가 없습니다. 또는 100 % 신뢰할 수없는 방법 중 하나를 시도해보십시오 (파일 시스템을 반복하거나 .class 파일을 찾는 JAR 파일 내에서 또는 내가 제안한 것과 같은 다른 접근법을 사용하여 시도). 특히, IDE는 파일 시스템을 처리한다는 것을 알고 있기 때문에 파일을 쉽게 반복 할 수 있습니다. 100 % 신뢰성. 런타임에는 쓸모가 없습니다. –

+0

아니면 ctrl + T를 눌러 Eclipse와 같은 IDE에서 클래스 계층 구조를 표시 할 수 있습니다. OP가 런타임/컴파일 시간에 솔루션을 원한다면 명확하지 않습니다. –

관련 문제