2009-11-29 58 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); 
} 
相关问题