[英]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類加載器,它將您連接到一個大型遠程代碼存儲庫)。
所以你的方法已經盡可能好了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.