2009-11-29 57 views
15

假設一個java代碼庫有一個名爲「com.example」的包。如果類加載器還沒有加載任何 -有沒有辦法強制類加載器加載一個包,即使它們的類沒有被加載?

在運行時,我們可以通過調用

Packages[] ps = Package.getPackages(); 

的問題是通過調用

Package p = Package.getPackage("com.example"); //(returns null) 

甚至得到所有包的列表得到這個包這些函數調用將無法使用它。我們可以迫使它先在包中的一個類加載包通過壓裝,像這樣:

this.getClass().getClassLoader().loadClass("com.example.SomeClass"); 
Package p = Package.getPackage("com.example"); //(returns non-null) 

然而,這是哈克,並需要提前知道一些類的名稱屬於包裹。

所以問題是 - 有沒有辦法通過名稱獲取Package實例,無論ClassLoader是否做了什麼?我對這種情況下類加載/包裝似乎如何工作的假設是否準確?

+0

謹防https://stackoverflow.com/questions/3455267/why-does-class-getpackage-return-the-same-package-for-classes-from-different-pac的 – Vadzim 2017-11-28 20:38:53

回答

11

或者,您可以使用類根目錄作爲起點,並遍歷所有* .class文件和子目錄。這隻有在你知道所有.class文件預先駐留在何處時纔有效。

所有這些的原因是Java有動態類加載,所以類可以在運行時從編譯時甚至啓動時未知的位置加載。因此,包的概念只是加載類的名稱空間,而不是您可以用來查看它們的目錄。

5

恐怕你的假設是無效的。類加載器在加載類時會進行包裝簿記。

你可以傳遞一個通配符到ClassLoader.getResources並強制它拿起包中的類,這反過來會做這件事。

您可以製作自己的ClassLoader,調用definePackage,但這對使用通常的香草類加載器沒有幫助。

5

我想你需要這個,因爲你需要檢查它的註釋。否則,你不會有興趣擁有一個只有操作都在訪問註釋的Package引用。這導致了這樣的假設,即您還有一些包含註釋的package-info.java。

如果您檢查java.lang.Package,您會看到getPackageInfo只是將package-info類加載爲普通類。

我有同樣的問題,並提出了這個解決方案。

public static Package getPackage(String packageName) throws ClassNotFoundException { 
    Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package 
    return Package.getPackage(packageName); 
} 
相關問題