Java 是否可以使用反射迭代包内的所有类?

Java 是否可以使用反射迭代包内的所有类?,java,reflection,Java,Reflection,我有一个有值的字符串。我想迭代调用特定方法的包中的所有类,如果该方法返回的值等于字符串中的值,则创建该类的对象 我希望以一种动态的方式来实现这一点,因此,如果我在这个包中添加一个类,它将自动出现在迭代中 有可能这样做吗如果没有,有办法做我想做的事吗? 我在期待类似的事情 for(Class clazz: SomeClass.listClasses("org.package")){ //code here } 不,这不可能以完全可靠的方式实现;然而,在许多情况下,它可能是实用的 由于

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

我希望以一种动态的方式来实现这一点,因此,如果我在这个包中添加一个类,它将自动出现在迭代中

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


我在期待类似的事情

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

不,这不可能以完全可靠的方式实现;然而,在许多情况下,它可能是实用的

由于java类加载器的灵活性,在特定的包下定义的类在运行时可能不知道(例如考虑一个特殊的类加载器,它可以通过在网络上加载它们,或者通过编译它们来临时定义类)。因此,没有标准的JavaAPI允许您在包中列出类

然而,实际上,您可以通过搜索所有类和JAR文件的类路径、构建完全限定类名的集合并根据需要搜索它们来实现一些技巧。如果您确信没有活动的类加载器会像前一段中描述的那样工作,那么这个策略就可以正常工作。例如(Java伪代码):

Map classesInPackage=newhashmap();
for(字符串项:eachClasspathEntry()){
if(isClassFile(条目)){
字符串packageName=getPackageName(条目);
如果(!classesInPackage.containsKey(packageName)){
put(packageName,newhashset());
}
get(packageName).add(getClassName(entry));
}else if(isJarOrZipFile(条目)){
//对每个JAR/ZIP文件条目执行相同的操作。。。
}
}
classesInPackage.get(“com.foo.bar”);//=>每个类的集合。。。

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


包中有很多关于如何创建和实例化代理的详细信息。

我可以想出两种方法来解决我认为您的问题,尽管这两种方法都不能真正迭代包中的所有类

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


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

“在此包中添加类”是什么意思?它是如何进入java进程的类路径的?@Jeffrey我在读关于反射的书,我认为这是唯一的方法,但我对反射一无所知。我尝试了一种“正常的方式”为包中的每个类添加一个验证,但我不希望这种方式,因为它不可扩展。@在开发时,我在包中添加了一些新类(所有类都扩展了一个名为Document的抽象类)。@RenatoDinhaniConceiço反射就是一种方式,但是你试过反射吗?那里有相当好的…我不认为这是一份值得反思的工作。更多的是文件系统/类加载器的工作。但是自定义类加载器至少在理论上是可以的。@Misarabevariable:想象一下,我编写了一个自定义类加载器,它通过返回一个类的字节码来实现
defineClass(String)
方法,该类通过给定的类名定义了一个空类。这是一个完全有效的类加载器,没有(实用的)方法列出它可以定义的每个类。是的,一般来说,这个问题是无法解决的。但对于特定的狭义情况则不同——我可能希望检查文件夹中的所有.class文件名称
plugins
,并在每个具有
register
方法的类上创建一个实例中文件夹中的任何新类文件classpath@MiserableVariable我不知道是否清楚,但我想加载的类是在开发时定义的,而不是在运行时定义的。