是否可以使用Reflection迭代包内的所有类?

我有一个有一些价值的字符串。 我想迭代调用特定方法的包中的所有类,如果方法返回的值等于我的String中的值,则创建该类的对象。

我想以动态方式执行此操作,因此如果我在此包中添加一个类,它将自动进行迭代。

这可能吗? 如果没有,有办法做我想要的吗?


我期待着类似的东西。

for(Class clazz: SomeClass.listClasses("org.package")){ //code here } 

不,这是不可能以完全可靠的方式; 但是,在许多情况下实施可能是实际的。

由于Java类加载器的灵活性,在特定包下定义的类可能在运行时不可知(例如,考虑一个特殊的类加载器,它可以动态地定义类,可能是通过从网络加载它们,或者编译它们的广告 – 特别)。 因此,没有标准的Java API允许您列出包中的类。

但实际上,您可以通过在类路径中搜索所有类和JAR文件,构建完全限定类名的集合以及根据需要搜索它们来做一些技巧。 如果您确定没有活动的类加载器将按照上一段中的描述运行,则此策略可以正常工作。 例如(Java伪代码):

 Map> classesInPackage = new HashMap(); for (String entry : eachClasspathEntry()) { if (isClassFile(entry)) { String packageName = getPackageName(entry); if (!classesInPackage.containsKey(packageName)) { classesInPackage.put(packageName, new HashSet()); } classesInPackage.get(packageName).add(getClassName(entry)); } else if (isJarOrZipFile(entry)) { // Do the same for each JAR/ZIP file entry... } } classesInPackage.get("com.foo.bar"); // => Set of each class... 

我可以想出两种方法来解决我认为你的问题,尽管它们都没有真正迭代一个包中的所有类。

一种是创建一个单独的文件,列出应该调用该特定方法的类。 这很容易实现。 您可能有一些工作创建文件,但这可以自动化。

第二个选项是在一些众所周知的地方查找.class文件 – 比如一个文件夹或一组文件夹 – 并猜测类名是什么并加载它。 如果这是一个简单的开发过程,则单个包中的类文件可能位于单个目录中。

是的,但不是一般案例解决方案。 您必须打包代码并以特定方式调用JVM。 具体来说,您需要创建一个Instrumentation代理,并调用java.lang.instrument.Instrumentation.getAllLoadedClasses()

java.lang.instrument的包文档包含有关如何创建和实例化代理的大量详细信息。