2013-03-27 2 views
2

주어진 클래스에 MyClassDescendant 개체를 채우는 정적 메서드가있는 추상 클래스 MyClass이 있습니다. 이 메서드는 getRandom() 메서드를 MyClassDescendant으로 호출하여 개체 인스턴스를 가져와야합니다. 인스턴스 또는 클래스 이름없이 클래스 개체를 얻는 방법

public static void populate(Collection<MyClass> coll, Class<? extends MyClass> cl, int num) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 
    for (int i = 0; i < num; i++) { 
     Method m; 
     m = cl.getMethod("getRandom"); 
     coll.add((MyClass)(m.invoke(null))); 
    } 
} 

가 그럼 난 그런 식으로 전화 :

나의 현재 코드는 다음과 같습니다

MyClass.populate((Collection<MyClass>)(Collection<?>)collection, MyClassDescendant.class, 3); 

이 코드는 작동하지만, 추한. 실제로 같을 것이다 달성하고 싶었다 무엇 :

MyClassDescendant.populate(collection, 3); 

는 정적 메서드 아니었다면, 난 그냥 this.getClass()을 사용하십시오. MyClass.class은 정적 메서드에서 작동하지만, MyClass에 대해서는 class을 원하지는 않지만 특정 MyClassDescendant (소수 유형이 있음)에 대해 알고 싶습니다.

인스턴스 또는 클래스 이름을 갖지 않고 클래스 객체를 가져올 수있는 방법이 있습니까?

+2

를 호출 할 수 있습니다. 대신 파생 클래스마다 구현하여 컬렉션에 해당 클래스의 인스턴스를 채울 수 있습니다. – niculare

+0

그래, 그게 효과가 있지만, 여러 클래스에 걸쳐 거의 동일한 코드를 복사하여 붙여 넣는 것을 피하고 싶습니다. – gronostaj

+0

항상 정적 컨텍스트에서 호출합니까? –

답변

1

정적 컨텍스트에 있기 때문에 일부 코드를 복제해야하지만 위임을 수행 할 수 있습니다. 이 방법은`기본 클래스는 정적에()`는 파생 클래스에서 오버라이드 (override) 할 수없는 채울 수 있기 때문에

public class MyClassDescendant extends MyClass { 
    public static void populate(Collection<MyClass> coll, int count) { 
     MyClass.populate(coll, MyClassDescendant.class, count); 
    } 
} 

이제 MyClassDescendant.populate(collection, 3);

+0

그건 영리하고 내 질문에 대답 해, 고마워. – gronostaj

0

랜덤을 얻는 것이 정적 인 방법이라면 방금 호출 할 수 없습니까?

public interface MyClassInterface { 
    MyClass getRandom(); 
} 

public abstract class MyClass implements MyClassInterface { 
    public static void populate(Collection<MyClass> coll, int num) { 
     for (int i = 0; i < num; i++) {    
      coll.add((MyClass)MyClassDescendant.getRandom()); 
     } 
    } 
} 

public class MyClassDescendant extends MyClass { 
    public MyClass getRandom() { 
     // implementation of getRandom 
    } 
} 
+0

'MyClassDescendant'만이 유일한 자손이 아니며, 그 유형이 거의 없습니다. 'MyClass'의 정적 추상 메소드'getRandom()'은이 문제를 해결할 수 있지만 Java는 정적 인 추상 메소드를 허용하지 않습니다. – gronostaj

+0

각각에 getRandom 메소드가있는 여러 자식을 원할 경우 인터페이스를 만들어 MyClass가 구현하도록해야합니다. –

+0

추상화가 불가능하다는 사실을 잊지 마십시오. –

0

은이 방식으로 방법을 구조 조정하십시오 :

하나의 코멘트에 관해서
public static <T extends Base> void populate(Collection<T> coll, int num) throws Exception{ 
    for (T item : coll) { 
     Method m; 
     m = item.getClass().getMethod("getRandom"); 
     coll.add((T)(m.invoke(null))); 
    } 
} 

, 당신은 또한 추상적 만들고 호출하여 getRandom() 방법에 대한 상속을 활용하기 위해 template method 디자인 패턴을 사용할 수 있습니다 그것은 당신의 populate 메서드 내에서.

+0

현재 반복 처리중인 컬렉션을 수정 중이므로 동시 수정 예외가 발생합니다. 게다가 콜렉션이 하늘의 경우, getRandom를 결코 호출하지 않습니다. –

+0

@ LeonardBrünings은 어떤 종류의'Collection'이 전달되고 있는지에 완전히 달려 있습니다. 두 번째 주석은 정확할 것 같습니다. 의도 한 기능입니다. – nattyddubbs

+0

내가 한 것을 이해하면이 메서드는 컬렉션의 각 요소를 반복하고 해당 클래스의 새로운 임의 인스턴스를 만듭니다. 이것은 내가하고 싶은 것이 아닙니다. 컬렉션은 * MyClass 하위 클래스의 * multiple * 유형을 보유해야하고, populate()는 특정 클래스 인스턴스의 수 *를 추가해야합니다. – gronostaj

관련 문제