我可以用反射或類似的東西來做嗎?如何獲得Java中以編程方式實現的所有接口的列表?
回答
是的,第一步是確定你關心的所有類。如果你已經有了這些信息,你可以枚舉它們中的每一個並使用instanceof來驗證關係。相關的文章在這裏:http://www.javaworld.com/javaworld/javatips/jw-javatip113.html
另外,如果你正在編寫一個IDE插件(你試圖做的事情比較常見),那麼IDE通常會爲你提供更有效的方法來訪問當前的類層次結構用戶代碼的狀態。
一般來說,這樣做很昂貴。要使用反射,該類必須加載。如果要加載類路徑中的每個類,則需要時間和內存,不建議使用。
如果你想避免這種情況,你需要實現你自己的類文件解析器,它可以更高效地運行,而不是反射。一個字節碼工程庫可能有助於這種方法。
Service Provider mechanism是列舉可插拔服務實現的常規手段。在Java 6中使用ServiceLoader
,或者在早期版本中實現您自己的。我在另一個答案中提供了an example。
埃裏克森說了些什麼,但如果你仍然想這樣做,那麼看看Reflections。從他們的網頁:
使用的反思,您可以查詢您的元數據:
- 得到一些類型
- 的所有亞型得到了一些註解
- 讓所有類型的標註有一些註釋所有類型註釋,包括匹配的註釋參數
- 獲取用一些註釋的所有方法
更具體:`新的思考(「my.package」)。getSubTypesOf(MyInterface.class)` – zapp 2013-03-16 13:12:35
埃裏克森說的是最好的。這裏有一個相關的問題和答案 - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
Apache BCEL庫允許您在不加載它們的情況下讀取類。我相信它會更快,因爲您應該可以跳過驗證步驟。使用類加載器加載所有類的另一個問題是您將遭受巨大的內存影響,並且無意中運行您可能不想執行的任何靜態代碼塊。
Apache的BCEL庫鏈接 - http://jakarta.apache.org/bcel/
我一直在尋找了一會兒,似乎有不同的方法,這裏是一個總結:
reflections庫,如果很受歡迎你不介意添加依賴項。它應該是這樣的:
Reflections reflections = new Reflections("firstdeveloper.examples.reflections"); Set<Class<? extends Pet>> classes = reflections.getSubTypesOf(Pet.class);
的ServiceLoader(按照埃裏克森的答案),它是這樣的:
ServiceLoader<Pet> loader = ServiceLoader.load(Pet.class); for (Pet implClass : loader) { System.out.println(implClass.getClass().getSimpleName()); // prints Dog, Cat }
注意,對於這個工作,你需要定義
Pet
作爲ServiceProviderInterface(SPI)並聲明其實現。你這樣做,用的名字examples.reflections.Pet
創造resources/META-INF/services
一個文件,並在examples.reflections.Dog examples.reflections.Cat
包級別的註解申報
Pet
所有實現。這裏有一個例子:Package[] packages = Package.getPackages(); for (Package p : packages) { MyPackageAnnotation annotation = p.getAnnotation(MyPackageAnnotation.class); if (annotation != null) { Class<?>[] implementations = annotation.implementationsOfPet(); for (Class<?> impl : implementations) { System.out.println(impl.getSimpleName()); } } }
和註釋定義:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PACKAGE) public @interface MyPackageAnnotation { Class<?>[] implementationsOfPet() default {}; }
,你必須聲明在一個名爲
package-info.java
該包內文件的包級別註解。這裏有樣本內容:@MyPackageAnnotation(implementationsOfPet = {Dog.class, Cat.class}) package examples.reflections;
注意,只有那些已知的ClassLoader當時包將通過調用加載到
Package.getPackages()
。
此外,還有基於URLClassLoader的其他方法,將永遠被限制在已經被加載,除非你做一個基於目錄的搜索類。
我遇到了同樣的問題。我的解決方案是使用反射來檢查ObjectFactory類中的所有方法,消除那些不是返回一個綁定POJO實例的createXXX()方法的方法。如此發現的每個類都被添加到Class []數組中,然後將其傳遞給JAXBContext實例化調用。這表現良好,只需加載即將需要的ObjectFactory類。我只需要維護ObjectFactory類,一個手工執行的任務(在我的情況下,因爲我開始使用POJO並使用schemagen),或者可以根據需要由xjc生成。無論哪種方式,它都是高性能,簡單和有效的。
Spring有一個非常簡單的方法來達致這:
public interface ITask {
void doStuff();
}
@Component
public class MyTask implements ITask {
public void doStuff();
}
然後你就可以自動裝配ITask
類型和Spring的列表將與所有的實現來填充它:
@Service
public class TaskService {
@Autowired
private List<ITask> tasks;
}
- 1. 如何獲得必須實現接口的所有方法?
- 2. Java EE CDI:以編程方式獲取同一接口的所有實例
- 3. Java,獲得實現特定接口的URLClassLoader的所有類
- 4. 如何獲得所有Python類型的列表(以編程方式)?
- 5. 如何獲得Guice的所有實現者/接口的子類?
- 6. 如何以編程方式獲得Orchard ContentItem的所有者?
- 7. 如何獲得實現指定接口的所有類
- 8. PHP:如何獲得實現某個接口的類的列表?
- 9. 如何以編程方式獲取sqlite中所有表的列表
- 10. 如何以TDD方式實現接口
- 11. 如何在Symfony中以編程方式獲得服務列表?
- 12. 如何以編程方式獲取站點中所有Sitecore域的列表?
- 13. 如何以編程方式在ABAP中列出所有表格?
- 14. 以編程方式檢索所有運輸方式的列表
- 15. 是否有可能獲得實現接口的所有類?
- 16. 如何以編程方式獲取WooCommerce中的所有產品?
- 17. 如何以編程方式獲得$(OutDir)?
- 18. TeamFoundation 2008 SDK - 如何以編程方式獲取所有變更集的列表?
- 19. 實現當接口獲得相同的接口,在Java超
- 20. 獲得實現接口的所有屬性
- 21. 如何以編程方式獲取接口的linux接口別名(IFLA_IFALIAS)?
- 22. 是否有可能獲得java包中所有接口的列表?
- 23. 以編程方式調用Java類中的所有方法
- 24. 如何以編程方式獲得NSDate plist表示形式?
- 25. 如何以編程方式列出Rails的所有控制器
- 26. 如何在android中以編程方式獲取所有連接設備的列表到一個路由器?
- 27. 如何以編程方式獲得java jstat -gcutil結果
- 28. 如何使用反射來獲取接口的所有實現?
- 29. 如何獲取類實現的所有接口?
- 30. 如何獲得我所有的實體映射表的列表?
是否有可能做它與一些神奇的Eclipse的快捷方式? ? – 2014-08-29 18:47:50