java 扫描所有子类_java获取全部子类或接口的全部实现
在JAVA中,獲取一個類的全部父類是比較簡單的,只需要通過反射(Class的getSuperclass()方法)即可。然而,如果想獲得一個類的所有子類,或者獲得實現某一個接口的所有實現類,相對比較麻煩。
用過Eclipse的開發人員都知道,通過F4鍵或(Ctrl+T組合鍵)可以查到指定類的類層次結構。仔細想一下該快捷鍵的實現原理,或許可以找到一個可行的設計思路。
首先,需要確定一個前提是,尋找所有子類,必須先指定搜索的文件范圍。打個比方,要尋找一個古人的所有后代成員,必須設置查找的地理范圍是在中國內,否則就無從入手。
結合實際的項目部署環境,查找子類的方法需要有兩種方式。第一種,在開發環境,可以直接遍歷指定范圍下的所有源代碼文件,再結合反射的知識;第二種,假設項目已經打成jar包,則只能通過jar包獲得所有類文件。
下面給出具體的代碼實現
1.若是開發環境,則通過遞歸查找指定目錄下的類文件的全路徑,代碼如下
1 /**
2 * 遞歸查找指定目錄下的類文件的全路徑3 *4 *@parambaseFile 查找文件的入口5 *@paramfileList 保存已經查找到的文件集合6 */
7 public static void getSubFileNameList(File baseFile, ListfileList) {8 if(baseFile.isDirectory()) {9 File[] files =baseFile.listFiles();10 for(File tmpFile : files) {11 getSubFileNameList(tmpFile, fileList);12 }13 }14 String path =baseFile.getPath();15 if (path.endsWith(".java")) {16 String name1 = path.substring(path.indexOf("src") + 4, path.length());17 String name2 = name1.replaceAll("\\\\", ".");18 String name3 = name2.substring(0, name2.lastIndexOf(".java"));19 fileList.add(name3);20 }21 }
獲取根路徑方法 final static File rootFolder = new File(SuperClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
2.若是jar包環境,則可以通過JarFile這個工具類,獲得所有全部類信息
1 /**
2 * 從jar包讀取所有的class文件名3 */
4 private static ListgetClassNameFrom(String jarName) {5 List fileList = new ArrayList();6 try{7 JarFile jarFile = new JarFile(newFile(jarName));8 Enumeration en = jarFile.entries(); //枚舉獲得JAR文件內的實體,即相對路徑
9 while(en.hasMoreElements()) {10 String name1 =en.nextElement().getName();11 if (!name1.endsWith(".class")) {//不是class文件
12 continue;13 }14 String name2 = name1.substring(0, name1.lastIndexOf(".class"));15 String name3 = name2.replaceAll("/", ".");16 fileList.add(name3);17 }18 } catch(IOException e) {19 e.printStackTrace();20 }21
22 returnfileList;23 }
3.從前兩步可以得到所有子類或所有接口實現類的類路徑信息,有了類的全路徑,就可以通過反射拿到類的信息,用來判斷是否滿足條件
1 /**
2 * 判斷一個類是否繼承某個父類或實現某個接口3 */
4 public static booleanisChildClass(String className, Class parentClazz) {5 if (className == null) return false;6
7 Class clazz = null;8 try{9 clazz =Class.forName(className);10 if (Modifier.isAbstract(clazz.getModifiers())) {//抽象類忽略
11 return false;12 }13 if (Modifier.isInterface(clazz.getModifiers())) {//接口忽略
14 return false;15 }16 } catch(Exception e) {17 e.printStackTrace();18 return false;19 }20 returnparentClazz.isAssignableFrom(clazz);21
22 }
4.寫幾個簡單的測試類,用來說明問題
1 packagebean;2
3 public abstract classAnimal {4 public abstract voideat();5 public abstract voidwalk();6 }
1 packagebean;2
3 public class Cat extendsAnimal{4
5 @Override6 public voideat() {7 System.err.println("小貓吃東西");8 }9
10 @Override11 public voidwalk() {12 System.err.println("小貓走路");13 }14
15 }
1 packagebean;2
3 public class Dog extendsAnimal{4
5 @Override6 public voideat() {7 System.err.println("小狗吃東西");8 }9
10 @Override11 public voidwalk() {12 System.err.println("小狗走路");13 }14
15 }
1 packagebean;2
3 public classPerson {4 privateString name;5 private intage;6
7 publicPerson(){8
9 }10 public Person(String name, intage) {11 super();12 this.name =name;13 this.age =age;14 }15
16 public voidsayHello(){17 System.err.println("hello,i am " + this.name);18 }19 }
5.入口方法,打印輸出結果(jar包可直接使用Eclipse導出可執行jar文件)
1 List fileList = new ArrayList();2
3 File baseFile = new File(getSrcPath() + File.separator + "src" + File.separator + "bean");4 if(baseFile.exists()){//開發環境,讀取源文件
5 getSubFileNameList(baseFile,fileList);6 }else{//jar包環境
7 fileList=getClassNameFrom("server.jar");8 }9 System.err.println("Animal類的所有子類有");10 for(String name:fileList){11 if(isChildClass(name,Animal.class))12 System.err.println(name);13 }
總結
以上是生活随笔為你收集整理的java 扫描所有子类_java获取全部子类或接口的全部实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java线程不执行_java线程池,阿里
- 下一篇: java 传递intent_java –