2013-12-22 29 views
2

是否有可能構造一個List<Object>其中的元素是無意義的類,目的是獲取列表元素之一併從該類運行靜態方法或實例化該類的新實例?此外,人們如何做到這一點,以及它爲什麼不可取(爲什麼)?Java未列出類的列表

要添加一些上下文:我想創建一個應用程序,生成一個隨機城市,將建築物放置在城市中,其中每個建築物是許多建築類中的一個的實例,每個建築類都從抽象基類繼承。要選擇適合某塊土地的建築物,程序可以遍歷所有可能建築物類別的列表,檢查是否可以滿足該建築物所需的參數(最小/最大高度,佔地面積,形狀等)或這些類可能以某種其他方式存儲,可能使用地圖或其他結構。底線是我需要存儲(拒絕?)到無根據的類。

+2

我會的「工廠列表,知道如何創建適當的對象「(如果切實可行),實際上取決於數據來自何處以及它具有何種作用。 – user2864740

+1

最好是'List '。 – chrylis

+0

這是一個非常好的建議,尤其令人印象深刻的是,考慮到您在添加上下文到我的帖子之前完成了它。我很可能走這條路。感謝這個想法。 –

回答

4

您不能存儲類型,但可以爲由JVM加載的每個類存儲Class對象。當JVM加載並初始化類路徑上的類時,它將爲該類創建一個單一的Class對象。

Class類使您可以訪問許多用於在程序上執行reflection的實例方法。

此外,如何做到這一點,以及它是如何不可取的(爲什麼)?

例如

List<Class<?>> classes = new ArrayList<>(); 
classes.add(Example.class); 

現在,你可以通過元素和調用不同的方法取決於你想要做什麼。如果你想創建一個新的實例(和你的類有一個無參數的構造函數),你可以做

classes.get(0).newInstance(); 

如果您還沒有一個無參數的構造函數,你需要得到Constructor引用Class對象。

如果您需要調用方法(無論是否爲static),則需要獲取Method參考。通讀javadoc

它是如何不明智的(以及爲什麼)?

有些事情你不能沒有反思,但它通常是不鼓勵的。


你應該嘗試使用反射來最小化時,你可以已經很好地使用Factory模式來實現你在這種情況下的目標。

User user2864740 suggests

我會的,如果可行的話「知道如何創建 合適的對象工廠」名單 - 真正依賴在這個 數據來自和它有什麼作用。

+0

這很好地回答了我的問題。 user2864740有一個很好的建議(評論我上面的原始問題),我認爲我可能會對任何人有同樣的問題感興趣。我認爲將這個建議加入到你的答案的開頭是件好事,因爲正如你所說,反思是「普遍灰心」(現在我回想起我的計算機科學教授幾乎完全相同的警告,他非常簡短地提到了反思)。 –

+0

@BigEndian該用戶提出的是在編譯時綁定你的類的替代方案(可能更好)。反射將綁定移到運行時間。 –

+0

是的,確切地說。在編譯時做事可以說是更乾淨更強大,這就是爲什麼我非常喜歡這個建議。 –

2

您可以實例化一個Class<?>這樣的情況 -

List<Class<?>> al = new ArrayList<>(); 
al.add(java.util.Date.class); 
for (Class<?> cls : al) { 
    try { 
    Constructor<?> ctor = cls.getConstructor(null); 
    Object o = ctor.newInstance(null); 
    System.out.println(o); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } 
} 

,當我剛跑了,輸出

Sun Dec 22 00:56:06 EST 2013 
+0

這對我非常有幫助,我的場景包含了迭代的類都擴展了一個抽象類,我可以將'Object o'轉換爲抽象類,然後調用抽象方法。我仍然懷疑自己的模式,但是你的回答幫助完成了我的循環。 – yamori