Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java反射-获取包列表_Java_Reflection - Fatal编程技术网

Java反射-获取包列表

Java反射-获取包列表,java,reflection,Java,Reflection,我正在构建一个Java应用程序,它有许多不同的包。我希望能够以编程方式告诉应用程序中存在哪些以特定预修复程序开头的包。Java反射API是否有这样的功能?我没有看到任何与反射API相关的内容 例如: com.app.controls.text com.app.controls.picker com.app.controls.date etc 我想通过了解前缀“com.app.controls”并了解新包将来可能会集成来列举所有这些 谢谢 您可以使用,它返回当前类加载器已知的所有包的数组。您必须

我正在构建一个Java应用程序,它有许多不同的包。我希望能够以编程方式告诉应用程序中存在哪些以特定预修复程序开头的包。Java反射API是否有这样的功能?我没有看到任何与反射API相关的内容

例如:

com.app.controls.text
com.app.controls.picker
com.app.controls.date
etc
我想通过了解前缀“com.app.controls”并了解新包将来可能会集成来列举所有这些

谢谢

您可以使用,它返回当前类加载器已知的所有包的数组。您必须手动循环遍历数组,并使用查找具有适当前缀的数组

下面是一个简单的例子:

public List<String> findPackageNamesStartingWith(String prefix) {
    return Package.getPackages().stream()
        .map(Package::getName)
        .filter(n -> n.startsWith(prefix))
        .collect(toList());
}
public List findPackageNamesStartingWith(字符串前缀){
return Package.getPackages().stream()
.map(包::getName)
.filter(n->n.startsWith(前缀))
.collect(toList());
}
请注意,此技术将仅返回在当前类装入器中定义的包。如果您需要来自不同类加载器的包,则有一些选项:

  • 安排一些事情,以便您的程序可以从类加载器内部运行上述代码。这需要一个特定的组织来支持您的代码库,这可能是可行的,也可能是不可行的

  • 使用反射在适当的类加载器上调用(通常受保护的)方法。如果程序在安全管理器下运行,这将不起作用

  • 基于并使用反射获取包列表-可能忽略空包:

    /**
     * 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;
    }
    
    /**
    *查找以前缀开头的所有包名称
    *@return包名集
    */
    公共集findAllPackagesStartingWith(字符串前缀){
    List ClassLoaderList=新建LinkedList();
    添加(ClasspathHelper.contextClassLoader());
    添加(ClasspathHelper.staticClassLoader());
    反射反射=新反射(新配置生成器()
    .setScanners(新的子扫描程序(false),新的资源扫描程序()
    .setURL(ClasspathHelper.forClassLoader(classLoaderList.toArray(新类加载器[0]))
    .filterInputsBy(新的FilterBuilder().include(FilterBuilder.prefix(“my.base.package”));
    
    设置不幸的是,当前类加载器不知道这些包。有没有其他可能的方法?可能没有,除了显式列出它们之外。@DerekGebhard:我想到了两种可能性。我已经将它们添加到了答案中。这些类中的大多数在我的本机库中不存在。你在使用第三方吗?@LordFarquaad这是一个旧的响应nse(2014年1月)我认为您的Java版本与我当时使用的版本相比是相当新的。