2013-03-27 60 views
2

我有一個抽象類MyClass用靜態方法來填充給出收集了一些MyClassDescendant對象。此方法應調用MyClassDescendant的靜態getRandom()方法來獲取對象實例。如何獲得類對象沒有實例或類名稱

我當前的代碼如下所示:

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將靜態方法的工作,但我不想classMyClass,但對於具體的MyClassDescendant(很少有傳人類型)。

有沒有什麼辦法讓類對象,而無需其實例或類的名字嗎?

+2

由於該方法'填充()'在基類是靜態的,它不能在派生類中重寫。相反,您可以在每個派生類中實現它以使用該類的實例填充集合。 – niculare 2013-03-27 18:26:31

+0

是的,這是行得通的,但我想避免在多個類中複製粘貼幾乎相同的代碼。 – gronostaj 2013-03-27 18:32:15

+0

你是否總是在靜態環境中調用它? – 2013-03-27 18:43:48

回答

1

既然你是在靜態情況下,你必須重複一些代碼,但你可以做的代表團。現在

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 2013-03-27 19:35:57

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 2013-03-27 18:29:33

+0

如果想讓多個孩子都有一個getRandom方法,你應該創建一個接口並讓MyClass實現它。 – 2013-03-27 18:37:22

+0

沒關係,忘了抽象方法不能成爲靜態的 – 2013-03-27 18:45:05

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))); 
    } 
} 

至於一個評論,您也可以通過使抽象的,並呼籲使用template method設計模式,利用繼承您getRandom()方法它在你的填充方法中。

+0

由於您正在修改您當前正在迭代的集合,因此您將遇到併發修改異常。此外,如果集合是空的,則永遠不會調用getRandom。 – 2013-03-27 18:40:48

+0

@LeonardBrünings完全取決於傳遞什麼樣的'集合'。你的第二個評論是正確的,它似乎是預期的功能。 – nattyddubbs 2013-03-27 18:43:56

+0

如果我明白你在那裏做了什麼,這個方法將迭代集合中的每個元素,並創建一個新的隨機它的類實例。這不是我想要做的。該集合應該包含多個MyClass類型的後代,並且應該添加一些特定類別的實例。 – gronostaj 2013-03-27 18:44:54

相關問題