try (ScanResult scanResult = new ClassGraph().whitelistPackages("x.y.z")
.enableClassInfo().scan()) {
for (ClassInfo ci : scanResult.getClassesImplementing("x.y.z.SomeInterface")) {
foundImplementingClass(ci); // Do something with the ClassInfo object
}
}
11条答案
按热度按时间s3fp2yjn1#
一般来说,这样做很昂贵。要使用反射,必须加载类。如果您想加载类路径上所有可用的类,这将花费时间和内存,不建议这样做。
如果您想避免这种情况,您需要实现自己的类文件解析器,它可以更有效地运行,而不是反射。字节码工程库可能有助于这种方法。
服务提供者机制是枚举可插拔服务实现的传统方法,随着Java9中jigsaw项目(模块)的引入,它变得更加成熟。使用
ServiceLoader
或者在早期版本中实现自己的。我在另一个答案中提供了一个例子。au9on6nz2#
是的,第一步是确定“所有”你关心的类。如果您已经有了这些信息,您可以枚举它们中的每一个,并使用instanceof验证关系。相关文章如下:https://web.archive.org/web/20100226233915/www.javaworld.com/javaworld/javatips/jw-javatip113.html
3zwtqj6y3#
就像埃里克森说的,但如果你还想这么做,那就看看反射。从他们的页面:
使用反射,您可以查询元数据:
获取某类型的所有子类型
使用一些注解对所有类型进行注解
使用一些注解获取所有类型的注解,包括注解参数匹配
使用一些
yrefmtwq4#
另外,如果您正在编写一个ide插件(您尝试做的是比较常见的),那么ide通常会为您提供更有效的方法来访问用户代码当前状态的类层次结构。
cfh9epnr5#
classgraph非常简单:
查找的实现的groovy代码
my.package.MyInterface
:dfuffjeb6#
一个新版本的@kaybee99的答案,但现在返回用户的问题:实现。。。
spring有一个非常简单的方法来实现这一点:
然后可以自动关联类型列表
ITask
spring将用所有实现填充它:uqjltbpv7#
列出实现给定接口的所有类的最健壮的机制目前是classgraph,因为它处理尽可能广泛的类路径规范机制数组,包括新的jpms模块系统(我是作者。)
j9per5c48#
埃里克森说的最好。下面是一个相关的问答线索-http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
apachebcel库允许您在不加载类的情况下读取类。我相信它会更快,因为你应该能够跳过验证步骤。使用类加载器加载所有类的另一个问题是,您将遭受巨大的内存影响,并且会无意中运行任何您可能不想执行的静态代码块。
apache bcel库链接-http://jakarta.apache.org/bcel/
6l7fqoea9#
spring有一个非常简单的方法来实现这一点:
然后可以自动关联类型列表
ITask
spring将用所有实现填充它:qyuhtwio10#
我已经搜索了一段时间,似乎有不同的方法,这里是一个总结:
如果您不介意添加依赖项,那么反射库非常流行。它看起来是这样的:
serviceloader(根据erickson的回答),它看起来是这样的:
请注意,要使其工作,您需要定义
Pet
并声明其实现。您可以通过在中创建一个文件来实现这一点resources/META-INF/services
有名字吗examples.reflections.Pet
并声明Pet
在里面包级别注解。举个例子:
以及注解定义:
并且必须在名为
package-info.java
在包裹里。以下是示例内容:请注意,只有类加载器当时知道的包才会通过调用
Package.getPackages()
.此外,还有其他基于urlclassloader的方法,除非您执行基于目录的搜索,否则这些方法将始终限于已加载的类。
aydmsdu911#
我也遇到了同样的问题。我的解决方案是使用反射来检查objectfactory类中的所有方法,消除那些不是create()方法的方法,这些方法返回一个绑定pojo的示例。这样发现的每个类都被添加到一个class[]数组中,然后该数组被传递给jaxbcontext示例化调用。这执行得很好,只需要加载objectfactory类,这是无论如何都需要的。我只需要维护objectfactory类,这个任务可以手工执行(在我的例子中,因为我从pojo开始使用schemagen),也可以根据xjc的需要生成。无论哪种方式,它都是高效、简单和有效的。