java 有没有办法强制类加载器加载一个包,即使它的任何类都没有被加载?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1816730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to force a classloader to load a package even if none of its classes have been loaded?
提问by mpobrien
Let's say a java codebase has a package called "com.example".
假设一个 Java 代码库有一个名为“com.example”的包。
At runtime, we can get this Package by calling
在运行时,我们可以通过调用来获取这个包
Package p = Package.getPackage( "com.example" ); //(returns null)
or even get a list of all packages by calling
甚至通过调用获取所有包的列表
Packages[] ps = Package.getPackages();
The problem is - if the ClassLoader has not yet loaded any class from the package, it won't be available to these function calls. We can force it to load the package by force-loading one of the classes in the package first, like this:
问题是 - 如果 ClassLoader 尚未从包中加载任何类,则这些函数调用将无法使用它。我们可以通过首先强制加载包中的一个类来强制它加载包,如下所示:
this.getClass().getClassLoader().loadClass( "com.example.SomeClass" );
Package p = Package.getPackage( "com.example" ); //(returns non-null)
However, this is hacky and requires knowing ahead of time the name of some class that belongs to the package.
然而,这很棘手,需要提前知道属于包的某个类的名称。
So the question is - is there any way to get an instance of Package by name, regardless of whether or not the ClassLoader has done anything? Are my assumptions about how classloading/packages seem to work in this situation accurate?
所以问题是 - 有没有办法按名称获取 Package 的实例,而不管 ClassLoader 是否做了任何事情?我关于类加载/包在这种情况下如何工作的假设是否准确?
采纳答案by avd
I assume you need this because you need to inspect its annotations. Otherwise you wouldn't be interested in having a Package reference which only operations are all around accessing annotations. This leads to the assumtion that you also have a package-info.java defined there with some annotations.
我假设你需要这个,因为你需要检查它的注释。否则,您将不会有兴趣拥有一个包引用,该引用只涉及访问注释的操作。这导致假设您还定义了一个 package-info.java 并带有一些注释。
If you check java.lang.Packageyou'll see that the getPackageInfojust loads the package-info class as an ordinary class.
如果您检查,java.lang.Package您会看到它getPackageInfo只是将 package-info 类加载为普通类。
I had the same problem and came up with this solution.
我遇到了同样的问题,并提出了这个解决方案。
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);
}
回答by Adriaan Koster
Alternatively you could use the class root directory as a starting point and walk through all *.class files and sub directories. This would only work if you know where all your .class files will reside beforehand.
或者,您可以使用类根目录作为起点并遍历所有 *.class 文件和子目录。这只有在您事先知道所有 .class 文件将驻留在何处时才有效。
The cause of all this is that Java has dynamic classloading, so classes can be loaded at runtime from locations not known at compile time or even at startup time. Therefore the concept of a package is just a namespace for loaded classes, not a directory which you can use to look them up.
这一切的原因是 Java 具有动态类加载,因此可以在运行时从编译时甚至启动时未知的位置加载类。因此,包的概念只是加载类的命名空间,而不是可用于查找它们的目录。
回答by bmargulies
I'm afraid that your assumptions are not valid. Classloaders do package book-keeping as they load classes.
恐怕你的假设不成立。类加载器在加载类时会进行包簿记。
You can pass a wildcard to ClassLoader.getResourcesand force it to pick up the classes in a package, which will in turn do the work.
您可以将通配符传递给ClassLoader.getResources并强制它选择包中的类,这将依次完成工作。
You can make your own ClassLoader that calls definePackage, but that won't help you with the usual vanilla classloaders in use.
您可以创建自己的 ClassLoader 来调用definePackage,但这对您使用的常用普通类加载器没有帮助。

