java 是否可以使用反射遍历包内的所有类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9898175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is possible iterate over all classes inside a package with Reflection?
提问by Renato Dinhani
I have a String with some value. I want to iterate over all classes in a package calling a specific method, and if the value returned by the method is equals the value in my String, create an object of that class.
我有一个具有某些价值的字符串。我想遍历调用特定方法的包中的所有类,如果该方法返回的值等于我的 String 中的值,则创建该类的对象。
I want do this in a dynamic way, so if I add a class in this package, it will automatically be in the iteration.
我想以动态方式执行此操作,因此如果我在此包中添加一个类,它将自动在迭代中。
Is possible do this? If not, there is a way to do what I want?
有可能这样做吗?如果没有,有没有办法做我想做的事?
I was expecting something like.
我期待着类似的东西。
for(Class clazz: SomeClass.listClasses("org.package")){
//code here
}
采纳答案by maerics
No, this is not possible in a totally reliable way; however, it may be practical to implement in many cases.
不,这不可能以完全可靠的方式进行;然而,在许多情况下实施可能是可行的。
Due to the flexibility of Java class loaders, the classes defined under a particular package may not be known at runtime (e.g. consider a special classloader which defines classes on-the-fly, perhaps by loading them from the network, or compiling them ad-hoc). As such, there is no standard Java API which allows you to list the classes in a package.
由于 Java 类加载器的灵活性,在特定包下定义的类在运行时可能是未知的(例如,考虑一个特殊的类加载器,它动态定义类,可能通过从网络加载它们,或编译它们——临时)。因此,没有标准的 Java API 允许您列出包中的类。
Practically speaking, however, you could do some tricks by searching the classpath for all class and JAR files, building a collection of fully-qualified class names, and searching them as desired. This strategy would work fine if you are sure that no active classloader will behave as described in the previous paragraph. For example (Java pseudocode):
然而,实际上,您可以通过搜索所有类和 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...
回答by Miserable Variable
I can think of two ways to solve what I think your problem is, though neither truly iterate over all classes in a package.
我可以想到两种方法来解决我认为您的问题,尽管它们都没有真正迭代包中的所有类。
One is to create a separate file that lists classes on which that specific method should be called. This is quite easy to implement. You might have some work creating the file, but that could be automated.
一种是创建一个单独的文件,列出应该调用特定方法的类。这很容易实现。您可能需要一些工作来创建文件,但这可以是自动化的。
The second option is to look for .class files at some well known place -- say a single folder or a set of folders -- and guess what the class name would be and load it. If this is a simple development process, the classfiles from a single package are probably in a single directory.
第二个选项是在某个众所周知的地方寻找 .class 文件——比如单个文件夹或一组文件夹——然后猜测类名是什么并加载它。如果这是一个简单的开发过程,则来自单个包的类文件可能位于单个目录中。
回答by ataylor
Yes, but not as a general case solution. You'll have to package up your code and invoke the JVM in specific way. Specifically, you'll need to create an Instrumentation agent, and call java.lang.instrument.Instrumentation.getAllLoadedClasses()
.
是的,但不是一般情况下的解决方案。您必须打包代码并以特定方式调用 JVM。具体来说,您需要创建一个 Instrumentation 代理,并调用java.lang.instrument.Instrumentation.getAllLoadedClasses()
.
The package documentation for java.lang.instrument
has lots of details on how to create and instantiate an agent.
的包文档java.lang.instrument
有很多关于如何创建和实例化代理的细节。