2011-06-01 61 views
3

是否有一些簡單的,探索性很強的方式來按包中的名稱搜索給定的類,並遞歸地在此包的所有子包中搜索給定的類?通過名稱遞歸搜索包中的Java類

I.e.鑑於現有的類,如:

  • foo.MyClass
  • foo.bar.baz.some.more.MyClass
  • foo.bar.baz.some.more.OtherClass

我想喜歡magicMethod("foo.bar.baz", "MyClass")運行的東西,並得到Class foo.bar.baz.some.more.MyClass作爲結果。很顯然,手動實現相當容易 - 通過探索來自Package.getPackages()的加載包,使用Class.forName(...)篩選適當的內容並在循環中尋找類,但可能存在標準Java庫或其他一些廣泛的庫,例如作爲Apache Commons,解決這個任務?

+0

公共的Java API不提供任何東西。該包始終是Java中類的不可分割的一部分。據我所知,沒有一個API函數可以接受或返回一個從包中分離出來的類名。 – x4u 2011-06-01 17:57:03

回答

5

我自己的OSS軟件的無恥插件:https://bitbucket.org/stevevls/metapossum-scanner/wiki,在maven central中可用。

的典型應用案例爲這個圖書館是做事情喜歡找實現這樣的類:

Set<Class<? extends MyDiscoverableHelper>> implementingClasses = new ClassesInPackageScanner() 
    .findImplementers("com.mypackage.service.impl", MyDiscoverableHelper.class); 

或註解類是這樣的:

Set<Class> entityClasses = new ClassesInPackageScanner() 
    .findAnnotatedClasses("com.mypackage.datamodel", javax.persistence.Entity.class); 

但選擇策略可以被交換通過實現一個接口並將其傳遞給掃描儀。如果你正在嘗試做的是找到名稱類,代碼片段是這樣的:

Set<Class> entityClasses = new ClassesInPackageScanner().setResourceNameFilter(new ResourceNameFilter() { 
    public boolean acceptResourceName(java.lang.String packageName, java.lang.String fileName) { 
     return fileName.equals("MyClass.class"); 
    } 
}).scan("foo"); 

我前一段時間寫了這個庫,因爲我從來沒有發現,我喜歡探索包的實現。有許多庫都有自己的內部API,但是我沒有知道它們將它打包在一個漂亮的API中。

另外,探索軟件包實際上很難得到正確的結果。這並不像起初看起來那麼直截了當!

+0

謝謝!看起來它是可行的方式!手動探索'Packages'證明是非常棘手的,這是正確的... – GreyCat 2011-06-02 13:14:13

+0

優秀...如果你確實檢查出來,我很樂意聽到任何反饋。我很可能很快就會發佈一個小版本。謝謝! – stevevls 2011-06-02 15:06:16

+0

我已經檢查過你的包 - 它的工作完美無瑕,但我們已經爲其他幾個主要與業務邏輯有關的原因(「字符串ID =>類」)進行了解決(我們還有一些基於這些「字符串ID」,所以我們不得不使用生成器)。無論如何,謝謝你的回答和優秀的圖書館:) – GreyCat 2011-06-10 19:35:30