簡體   English   中英

在Jar中查找實現接口的類

[英]Find classes implementing an interface in 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個類文件並查找它是否已實現接口。 有沒有有效的方法呢?

Reflections庫可以做到這一點:

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

Spring在ClassPathScanningCandidateComponentProvider有一些幫助代碼,但它基本上就是你做的。

您可能還想查看Freud ,這是一個編寫靜態分析測試的舒適工具包,例如確保某個包中的所有類或實現某個接口的所有類也實現equals()hashCode()

關於Freud的好處是它可以分析Java 源代碼和類文件(即源代碼和編譯的字節代碼),它可以查看屬性或文本文件,它可以讀取CSS和Spring配置(因此它可以確保所有重要的DAO bean的方法有@Transactional )。

任何現代IDE(eclipse,IntelliJ,...)都應該能夠找到特定接口(或類或方法)的用法。

如果您擁有jar文件的源,則可以將其作為項目的依賴項添加。 或者,您只需解壓縮jar的內容並將其作為IDE中的項目打開,並找到您感興趣的界面的用法。

一般來說,沒有簡單的方法。 甚至沒有獲得該信息的通用方法。

這里的問題在於Java的類加載機制。 在實際加載接口之前,您無法判斷類是否實現了接口。 並且您無法在不嘗試加載類的情況下判斷是否存在類(請注意,您甚至無法確定類路徑上哪些類可用 )。

這里的原因很簡單,類加載器不提供任何枚舉類功能,原因是類路徑可能無限大/深,並且檢索該枚舉的成本(及時)可能是無限的(想想一個URL類加載器,它將您連接到一個大型遠程代碼存儲庫)。

所以你的方法已經盡可能好了。

你可以使用IntelliJ。 創建一個虛擬項目,並將您的jar添加到classpath。 然后打開界面,單擊界面名稱左側的(I)圖標。 不確定Eclilse,但很確定你也可以這樣做。

課程也一樣。

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM