有没有办法强制类加载器加载包,即使它的类没有被加载?

mpo*_*ien 15 java class classloader package

假设java代码库有一个名为"com.example"的包.

在运行时,我们可以通过调用获取此包

Package p = Package.getPackage( "com.example" ); //(returns null)
Run Code Online (Sandbox Code Playgroud)

甚至可以通过调用获得所有包的列表

Packages[] ps = Package.getPackages();
Run Code Online (Sandbox Code Playgroud)

问题是 - 如果ClassLoader尚未从包中加载任何类,则它们将无法用于这些函数调用.我们可以通过首先强制加载包中的一个类来强制它加载包,如下所示:

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

但是,这很hacky并且需要提前知道属于该包的某个类的名称.

所以问题是 - 有没有办法按名称获取Package的实例,无论ClassLoader是否做了什么?关于类加载/包在这种情况下如何工作的假设是否准确?

Adr*_*ter 11

或者,您可以使用类根目录作为起点,并遍历所有*.class文件和子目录.这只有在您事先知道所有.class文件所在的位置时才有效.

所有这些的原因是Java具有动态类加载,因此可以在运行时从编译时未知的位置或甚至在启动时加载类.因此,包的概念只是加载类的命名空间,而不是可用于查找它们的目录.


bma*_*ies 5

我担心你的假设是无效的.类加载器在加载类时会打包簿记.

你可以传递一个通配符ClassLoader.getResources并强制它来获取包中的类,这将依次完成工作.

您可以创建自己的ClassLoader来调用definePackage,但这对使用中常用的vanilla类加载器没有帮助.


avd*_*avd 5

我假设你需要这个,因为你需要检查它的注释.否则,您不会对包引用感兴趣,只有操作才能访问注释.这导致了一个假设,你也有一个带有一些注释的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);
}
Run Code Online (Sandbox Code Playgroud)