2013-03-09 113 views
8

我可以用反射或類似的東西來做嗎?是否有可能獲得實現接口的所有類?

+4

爲什麼這麼多downvotes?這是一個完全有效的問題! – 2013-03-09 06:05:07

+1

可能的重複http://stackoverflow.com/questions/347248,http://stackoverflow.com/questions/435890 – StarPinkER 2013-03-09 06:06:26

+0

嘗試[這](http://tinyurl.com/d5ohdr4) – 2013-03-09 06:09:14

回答

9

有沒有100%可靠的方法來做你想做的。原因是因爲Java中的類加載是如何工作的。

Java中的類按需「加載」。第一次在代碼中引用類(靜態或動態)時,JVM將使用當前的類加載器並嘗試加載它。 ClassLoader沒有方法給出所有可以從中加載的類,因此不能迭代類。

有一些不可靠的解決方法。例如,如果您知道您的ClassLoader只會從特定目錄或特定的JAR文件中加載類,則可以使用與您的文件系統相關的類來查找可用的「.class」文件,然後您可以加載所有東西(這需要花費時間並且會消耗很多的PermGen,這可能是一個問題 - 記住,你不能輕易地卸載一個類!)(除非你做了一些ClassLoader魔術),並且使用反射來過濾實現你的類接口。

此變通辦法的問題是,如果您更改了部署,它很可能會停止工作。例如,如果您開始部署JAR文件,稍後您決定使用將處理WAR文件的servlet容器,那麼您的代碼可能無法工作。

如果你真的想嘗試這種方法,有一個名爲Reflections的項目可能會有用。

我曾經實現過的最可靠的方法是使用註釋處理器。您編寫註釋,註釋接口,編寫一些代碼,編譯時會執行這些代碼,這些代碼將收集實現您的接口的類並將其名稱保存在資源文件中。然後用一個讀取該文件的方法編寫一個類,併爲該資源文件中列出的每個類名提供一個Class對象。

這種方法的問題是,只有在我的構建過程中編譯的類纔會被列出(例如,如果您使用接口發佈庫並期望其他人實現您的接口,則此方法將不會有用,因爲你的代碼永遠不會知道別人項目中的類)。如果這對於你來說已經足夠了,就像我一樣,這個解決方案完美無瑕。我可以在帶有WAR(部署或不部署)的Servlet容器中使用它,在可執行文件中使用它。它會一直工作。

+0

真的嗎?我的IDE做得很好... – 2013-03-09 06:07:08

+0

@BrianRoach,哦,真的嗎?現在,您可以要求您的IDE列出您的類,然後按CTRL + C列表,在代碼中的某處添加CTRL + V(並且每次添加新類時手動更新),或者IDE知道它完全是事實對於您正在運行的代碼無用。或者你嘗試一種不是100%可靠的方法(迭代你的文件系統,或者在JAR文件中找到.class文件,或者使用不同的方法,比如我建議的方法)。具體來說,IDE知道它正在處理文件系統,因此它可以輕鬆地迭代文件。 100%可靠。運行時無用。 – 2013-03-09 06:18:04

+0

或者你可以按下ctrl + T,並允許像eclipse這樣的IDE向你展示類層次結構。目前還不清楚OP是否需要在運行時/編譯時提供解決方案。 – 2013-03-09 06:22:02

相關問題