Java 反射 - 获取包列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13944633/
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
Java Reflection - Get List of Packages
提问by Derek Gebhard
I am building a Java app that has a number of different packages. I want to be able to tell programmatically which packages exist in the app that start with a specific pre-fix. Is there anyway to do this with the Java reflection APIs? I didn't see anything like this related to the reflection apis.
我正在构建一个包含许多不同包的 Java 应用程序。我希望能够以编程方式告诉应用程序中存在哪些以特定前缀开头的包。有没有办法用 Java 反射 API 来做到这一点?我没有看到任何与反射 api 相关的内容。
Example:
例子:
com.app.controls.text
com.app.controls.picker
com.app.controls.date
etc
I want to enumerate all of these by knowing the prefix "com.app.controls" and understanding that a new package might get integrated in the future.
我想通过了解前缀“com.app.controls”并了解将来可能会集成一个新包来列举所有这些。
Thanks!
谢谢!
回答by Sean Reilly
You can do this by using Package.getPackages(), which returns an array of all packages known to the current class loader. You'll have to manually loop through the array and find the ones with the appropriate prefix using getName().
您可以通过使用Package.getPackages()来做到这一点,它返回当前类加载器已知的所有包的数组。您必须手动遍历数组并使用getName()找到具有适当前缀的数组。
Here's a quick example:
这是一个快速示例:
public List<String> findPackageNamesStartingWith(String prefix) {
return Package.getPackages().stream()
.map(Package::getName)
.filter(n -> n.startsWith(prefix))
.collect(toList());
}
Note that this technique will only return the packages defined in the current class loader. If you need the packages from a different class loader, there are some options:
请注意,此技术将仅返回在当前类加载器中定义的包。如果您需要来自不同类加载器的包,有一些选项:
Arrange things so that your program can run the above code from inside that class loader. This requires a certain organisation to your code base, which may or may not be feasible.
Use reflection to call the (normally protected) method getPackages()on the appropriate class loader. This won't work if the program is running under a security manager.
安排一些事情,以便您的程序可以从该类加载器内部运行上述代码。这需要对您的代码库进行某种组织,这可能可行,也可能不可行。
使用反射在适当的类加载器上调用(通常受保护的)方法getPackages()。如果程序在安全管理器下运行,这将不起作用。
回答by BLuEGoD
Based on Sean's answerand using reflection to get a list of packages - possibly ignoring empty ones:
基于肖恩的回答并使用反射来获取包列表 - 可能会忽略空包:
/**
* Finds all package names starting with prefix
* @return Set of package names
*/
public Set<String> findAllPackagesStartingWith(String prefix) {
List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false), new ResourcesScanner())
.setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("my.base.package"))));
Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);
Set<String> packageNameSet = new TreeSet<String>();
for (Class classInstance : classes) {
String packageName = classInstance.getPackage().getName();
if (packageName.startsWith(prefix)) {
packageNameSet.add(packageName);
}
}
return packageNameSet;
}