2012-09-21 3 views
3

나는 인스턴스를 필요로하는 250 개 이상의 하위 클래스가 있으며 거기에 앉아서 수줍음을 붙여 new Class(); 번 250 번 붙여 넣을 수 없습니다. 어쨌든 Reflection을 사용하여 수업의 기초를 마련합니까? 인스턴스를 만들 때 생성자가 필요하지 않습니다. 감사합니다. .모든 하위 클래스의 인스턴스를 만드는 방법

+0

우리는이보다 더 많은 정보가 필요합니다. 이러한 인스턴스는 어디에서 생성되어야합니까? 일부 코드가 도움이 될 것입니다. – Keppil

+0

@Keppil 인스턴스가 없으므로 인스턴스를 만들어야합니다. 내 프로그램을 시작할 때 만들어야합니다. – user1681891

+0

나는 그 클래스의 이름을 알고 있다고 가정하고 그 클래스의 전체 목록과 생성하려는 인스턴스의 수를 알고 있습니까? –

답변

3

난 정말 당신을 undesrtand하지 않지만, 그런 것 같아요 (테스트하지)하려고 :

public class Test { 
    public static void main(String[] args) { 
     Class[] classes = new Class[]{Class1.class, Class2.class, Class3.class}; 
     for (Class cls : classes) { 
      Object myObject = cls.newInstance(); 
      -------^^^^^^^^------- 
     } 
    } 
} 

Creating New Class Instances에서 편집 : 는 http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String)

Class.forName("mypackage.MyClassname"); 
+0

그 정도는 알고 있지만 클래스 이름없이 모든 것을해야합니다. 모든 clases에 대해 루프를 실행하고 해당 수퍼 클래스가 다른 클래스 (Class.getSuperclass())인지 확인한 다음 인스턴스를 확인해야합니다. – user1681891

0
수 있음

다음과 같이 할 수 있습니다.

Class instantiableClass = Class.forName("package.subpackage.ClassName"); 
Object instance = instantableClass.newInstance(); 

클래스에 기본 생성자 또는 public 0 args 생성자 만있는 경우에만 작동합니다. 필요한 경우 코드가 반복되거나 일반화되거나 재현 될 수 있습니다.

더 일반적인 해결 방법은 this을 사용하는 것이 왜 가능하지 않은지 이해하는 데 도움이 될 수 있습니다. 당신은 당신이 알고있는 모든 수업에서 원하는 것을 할 수 있고, 그들의 이름을 알고 있거나, 어떤 출처에서든지 그들의 이름에 접근 할 수 있으며, 어떤 식 으로든 최소한의 정보를 제공받을 수 있습니다.

하지만 그 클래스에 대한 지식이 없으면 거의 불가능합니다. 현재 클래스 경로에있는 모든 클래스를 찾은 다음 특정 클래스를 준수하도록 상속 트리를 chceck해야합니다.

0
코드의 덩어리가 (내 모든 클래스 Commande에서 상속), 패키지의 모든 클래스를로드 할 새로운 인스턴스를 생성하고 해시 맵에 넣어하기의

: 여기

this.actions = new HashMap<String, Commande>(); 

    ServletContext sc = this.getServletContext(); 

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    URL res = classLoader.getResource(COMMAND_DIRECTORY); 
    File[] list = new File(res.getFile()).listFiles(); 
    String className = ""; 
    for (File f : list) { 
     className = f.getName().replaceAll(".class$", ""); 
     try { 
      Class<?> classe = Class.forName("org.commandes." + className); 
      if (classe.getSuperclass() == Commande.class) { 
       Commande c = (Commande) classe.newInstance(); 
       this.actions.put(c.getName(), c); 
      } 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (InstantiationException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

을 COMMAND_DIRECTORY 나를위한 조직/명령입니다.

이것이 올바른 방법인지는 모르겠지만 서블릿에 명령 디자인 패턴 (구현 된 플러그인과 유사 함)을 구현하는 방법을 찾은 유일한 방법입니다.

2

먼저 get all the subclasses이 필요합니다. 그 특별한 대답은 내가 직접 시험하지는 않았지만 합법적으로 보인다.

그런 다음 전달해야하는 생성자에 대한 매개 변수가있는 경우 클래스를 반복하고 Class.newInstance (인수 없음 생성자) 또는 Class.getConstructorConstructor.newInstance을 사용하여 인스턴스를 만듭니다. 최종 코드는 다음과 같습니다.

이렇게하면 하위 클래스를 가져 와서 반복하고 각각의 인스턴스를 만듭니다. 여기에 몇 가지 예외가 있습니다. 당신도 캐스팅을해야 할 수도 있습니다.

편집 : 위의 대답을 보면 가짜 클래스 로딩이 발생할 수 있습니다.서브 클래스 like this instead 당신의 세트를 만듭니다

Reflections reflections = new Reflections(...); //see in other use cases 
Set<String> subTypeFqns = reflections.getStore().getSubTypesOf(SomeClass.class.getName()); 
Set<Class<?>> subTypes = new HashSet<Class<?>>(); 
for (String fqn : subTypeFqns) { 
    subTypes.add(Class.forName(fqn)); 
} 

을 다음이 줄을 :

for (Class<? extends SubType> subType : subTypes) { 
    someTypes.add(subType.newInstance()); 
} 

이되기 :

for (Class<?> subType : subTypes) { 
    someTypes.add((SomeType) subType.newInstance()); 
} 
+0

하위 서브 클래스도 얻을 수 있으므로 하위 클래스가 필요 없으면'subType.getSuperclass(). equals (SomeType.class)'를 사용하여 반복 할 때 필터링 할 수 있습니다. – Brian

관련 문제