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

Posted

技术标签:

【中文标题】有没有办法强制类加载器加载一个包,即使它的类都没有被加载?【英文标题】:Is there a way to force a classloader to load a package even if none of its classes have been loaded? 【发布时间】:2010-12-21 11:08:51 【问题描述】:

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

在运行时,我们可以通过调用得到这个Package

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

甚至通过调用获取所有包的列表

Packages[] ps = Package.getPackages();

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

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

但是,这很麻烦,需要提前知道属于包的某个类的名称。

所以问题是 - 有没有办法通过名称获取 Package 的实例,而不管 ClassLoader 是否做了任何事情?我对类加载/包在这种情况下如何工作的假设是否准确?

【问题讨论】:

提防***.com/questions/3455267/… 【参考方案1】:

我假设你需要这个,因为你需要检查它的注释。否则,您不会对拥有仅围绕访问注释的操作的包引用感兴趣。这导致假设您还在那里定义了一个带有一些注释的 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);

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

恐怕你的假设不成立。类加载器在加载类时会记账。

您可以将通配符传递给 ClassLoader.getResources 并强制它选择包中的类,这将依次完成工作。

您可以制作自己的调用definePackage 的类加载器,但这对您使用常用的普通类加载器没有帮助。

【讨论】:

以上是关于有没有办法强制类加载器加载一个包,即使它的类都没有被加载?的主要内容,如果未能解决你的问题,请参考以下文章

系统的类加载器

系统的类加载器

JVM类加载器

JVM类加载器

Composer,我的包中的类没有在使用它的应用程序中自动加载

Java类加载器