使用Java反射获取包名(Get package names using java reflecti

2019-06-27 13:42发布

我想从一个单独的Java项目中的所有包的名字,我会怎么做这在Java中最好使用反射?

我已经导入项目到我的构建路径,我已经使用下面的代码来获取包名审判。

Package[] pack = Package.getPackages();

编辑:我不使用jar文件,我刚才导入的项目,因为它会在同一目录。 我只需要我创建的软件包,它具有一定的目录开始专门包。

Answer 1:

你真的不能仅通过使用知道库每包名getPackages()因为它不仅会列出已知的类加载器的人。 这意味着,如果一个类还没有从一个特定的软件包加载,那么这将是从列表中缺席。

使用zip文件处理程序打开jar文件,并读出目录名的包。 利用这种技术,你会发现所有的包名,即使是那些没有“使用中”。 基本上,包含任何路径.class文件是一个“包名”。

----编辑为进一步的细节显示没有被使用的JAR文件---

由于没有使用JAR文件(为什么不呢?他们真的很不错!),你就必须扫描目录。 “发现”的目录,你需要砍类路径。 获取类路径的方法是:

 String classpath = System.getProperty("java.class.path", null);

然后,你这样做,有一个每一个“起点”下一个搜索所有目录.class在它的文件。 一旦你拥有所有这些,你把所有的软件包。

再次,这是不可能通过只要求类加载器知道所有的包,除非你能以某种方式保证类加载器加载的所有类(它通常不)的。



Answer 2:

只要你不需要空包,这样的事情应该工作:

/**
 * Finds all package names
 * @return Set of package names
 */
public Set<String> findAllPackages() {
    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) {
        packageNameSet.add(classInstance.getPackage().getName());
    }
    return packageNameSet;
}

它发现的所有类,通过他们循环,并获得存储在一组,以避免重复包名。

不幸的是,我们不能只用下面正常思考对象的代码,而无需指定自定义配置,让物体扫描。

Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);


文章来源: Get package names using java reflections