在Jar中查找实现接口的类

我想找出jar中的类是否已经实现了特定的接口。 我已经实现了下面的代码,但它遍历jar文件中的所有类,并在每个类上查找它是否已实现此特定接口。

public static synchronized boolean findClassesInJar(final Class baseInterface, final String jarName){ final List classesTobeReturned = new ArrayList(); if (!StringUtils.isBlank(jarName)) { //jarName is relative location of jar wrt. final String jarFullPath = File.separator + jarName; final ClassLoader classLoader = this.getClassLoader(); JarInputStream jarFile = null; URLClassLoader ucl = null; final URL url = new URL("jar:file:" + jarFullPath + "!/"); ucl = new URLClassLoader(new URL[] { url }, classLoader); jarFile = new JarInputStream(new FileInputStream(jarFullPath)); JarEntry jarEntry; while (true) { jarEntry = jarFile.getNextJarEntry(); if (jarEntry == null) break; if (jarEntry.getName().endsWith(".class")) { String classname = jarEntry.getName().replaceAll("/", "\\."); classname = classname.substring(0, classname.length() - 6); if (!classname.contains("$")) { try { final Class myLoadedClass = Class.forName(classname, true, ucl); if (baseInterface.isAssignableFrom(myLoadedClass)) { return true; } } catch (final ClassNotFoundException e) { } } } } return false; } 

有没有简单的方法来做到这一点? 因为如果有一个包含100个类文件且第100个类的jar已经实现了这个接口,通过上面的代码,我需要迭代所有100个类文件并查找它是否已经实现了接口。 有没有有效的方法呢?

Reflections库可以做到这一点:

 Reflections reflections = new Reflections( ClasspathHelper.forPackage("your.root.package"), new SubTypesScanner()); Set> implementingTypes = reflections.getSubTypesOf(YourInterface.class); 

Spring在ClassPathScanningCandidateComponentProvider有一些帮助代码,但它基本上完成了你的工作。

您可能还想查看Freud ,这是一个编写静态分析测试的舒适工具包,例如确保某个包中的所有类或实现某个接口的所有类也实现equals()hashCode()

关于Freud的好处是它可以分析Java 源代码和类文件(即源代码和编译的字节代码),它可以查看属性或文本文件,它可以读取CSS和Spring配置(因此它可以确保所有重要的DAO bean的方法有@Transactional )。

一般来说,没有简单的方法。 甚至没有获得该信息的通用方法。

这里的问题在于Java的类加载机制。 在实际加载接口之前,您无法判断类是否实现了接口。 而且你无法判断一个类是否存在而没有尝试加载它(请注意,你甚至无法分辨类路径上哪些类可用 )。

这里的原因很简单,类加载器不提供任何枚举类function,原因是类路径可能无限大/深,并且检索该枚举的成本(及时)可能是无限的(想想一个URL类加载器,它将您连接到一个大型远程代码存储库)。

所以你的方法已经尽可能好了。

任何现代IDE(eclipse,IntelliJ,…)都应该能够找到特定接口(或类或方法)的用法。

如果您有jar文件的源代码,则可以将其作为依赖项添加到项目中。 或者,您只需解压缩jar的内容并将其作为IDE中的项目打开,并找到您感兴趣的界面的用法。

您可以使用IntelliJ。 创建一个虚拟项目,并将您的jar添加到classpath。 然后打开界面,单击界面名称左侧的(I)图标。 不确定Eclilse,但很确定你也可以这样做。

课程也一样。

在此处输入图像描述