我有一个有一些价值的字符串。我想迭代调用特定方法的包中的所有类,如果方法返回的值等于我的String中的值,则创建该类的对象。
我想以动态方式执行此操作,因此如果我在此包中添加一个类,它将自动处于迭代中。
这可能吗? 如果没有,有办法做我想做的事吗?
我期待像。
for(Class clazz: SomeClass.listClasses("org.package")){
//code here
}
答案 0 :(得分:8)
不,这是不可能完全可靠的;但是,在许多情况下实施可能是切合实际的。
由于Java类加载器的灵活性,在特定包下定义的类在运行时可能不知道(例如,考虑一个特殊的类加载器,它可以即时定义类,可能是通过从网络加载它们,或者编译他们ad-hoc)。因此,没有标准的Java API允许您列出包中的类。
但实际上,您可以通过在类路径中搜索所有类和JAR文件,构建完全限定类名的集合以及根据需要进行搜索来做一些技巧。如果您确定没有活动的类加载器将按照上一段中的描述运行,则此策略可以正常工作。例如(Java伪代码):
Map<String, Set<String>> classesInPackage = new HashMap();
for (String entry : eachClasspathEntry()) {
if (isClassFile(entry)) {
String packageName = getPackageName(entry);
if (!classesInPackage.containsKey(packageName)) {
classesInPackage.put(packageName, new HashSet<String>());
}
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<String> of each class...
答案 1 :(得分:2)
我可以想出两种解决我认为你的问题的方法,虽然它们都没有真正迭代一个包中的所有类。
一种是创建一个单独的文件,列出应该调用该特定方法的类。这很容易实现。您可能有一些工作创建文件,但这可以自动化。
第二个选项是在一些众所周知的地方查找.class文件 - 比如一个文件夹或一组文件夹 - 并猜出类名是什么并加载它。如果这是一个简单的开发过程,则单个包中的类文件可能位于单个目录中。
答案 2 :(得分:1)
是的,但不是一般案例解决方案。您必须打包代码并以特定方式调用JVM。具体而言,您需要创建一个Instrumentation代理,并调用java.lang.instrument.Instrumentation.getAllLoadedClasses()
。
包documentation for java.lang.instrument
有很多关于如何创建和实例化代理的详细信息。