2012-08-29 51 views
3

我想从单独的Java项目中获取所有软件包名称,如何在Java中使用反射来完成此操作?使用java反射获取软件包名称

我已经将项目导入到我的构建路径中,并尝试使用下面的代码来获取软件包名称。

Package[] pack = Package.getPackages();

编辑:我不使用jar文件,我刚才导入的项目,因为它会在同一目录。我只需要创建的包,特别是以特定目录开头的包。

+0

*“我想从一个单独的Java项目中的所有包的名字,我会怎么做这在Java中最好使用反射?” *什么是最终用户从所有这些恶作剧得到什么?您想要提供哪些**应用程序功能? –

回答

6

只使用getPackages(),你实在无法知道库中的每个包名,因为它只会列出classloader已知的包名。这意味着如果一个类尚未从特定包中加载,那么它将不在列表中。

使用压缩文件处理例程打开jar文件,并按目录名读出软件包。使用这种技术,您将发现所有软件包名称,即使那些尚未“使用”的软件包名称。基本上,包含.class文件的任何路径都是“包名称”。

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

既然你不使用JAR文件(为什么不呢?他们真的很不错!),你将有扫描目录。要“查找”目录,您需要切断课程路径。获取类路径的方法是:

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

那么你就具有.class文件中的每一个它“出发点”下一个搜索的所有目录。一旦你拥有了所有这些,你拥有所有的软件包。除非你能以某种方式保证类加载器已经加载了所有类(通常不会),否则不可能通过询问类加载器来知道所有的包。

+0

这不起作用。详情请参阅编辑。 – Colin747

+0

查看更新,并考虑在jar文件中打包您的类。 –

0

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

/** 
* 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; 
} 

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

不幸的是,我们不能只使用正常的Reflections对象下面的代码,而不指定自定义配置来允许对象扫描。

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