在Jar中查找实现接口的类

时间:2013-05-14 14:52:27

标签: java interface jar

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

    public static synchronized boolean findClassesInJar(final Class<?> baseInterface, final String jarName){
        final List<String> classesTobeReturned = new ArrayList<String>();
        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个类文件并查找它是否已实现接口。有没有有效的方法呢?

5 个答案:

答案 0 :(得分:10)

Reflections库可以做到这一点:

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

答案 1 :(得分:3)

Spring在ClassPathScanningCandidateComponentProvider中有一些帮助代码,但它基本上就是你所做的。

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

关于弗洛伊德的好处是它可以分析Java 源代码和类文件(即源代码和编译的字节代码),它可以查看属性或文本文件,它可以读取CSS和Spring配置(因此它可以确保DA​​O bean的所有重要方法都有hashCode())。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分:0)

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

课程也一样。

enter image description here