java 扫描所有子类_java获取全部子类或接口的全部实现
在JAVA中,獲取一個(gè)類(lèi)的全部父類(lèi)是比較簡(jiǎn)單的,只需要通過(guò)反射(Class的getSuperclass()方法)即可。然而,如果想獲得一個(gè)類(lèi)的所有子類(lèi),或者獲得實(shí)現(xiàn)某一個(gè)接口的所有實(shí)現(xiàn)類(lèi),相對(duì)比較麻煩。
用過(guò)Eclipse的開(kāi)發(fā)人員都知道,通過(guò)F4鍵或(Ctrl+T組合鍵)可以查到指定類(lèi)的類(lèi)層次結(jié)構(gòu)。仔細(xì)想一下該快捷鍵的實(shí)現(xiàn)原理,或許可以找到一個(gè)可行的設(shè)計(jì)思路。
首先,需要確定一個(gè)前提是,尋找所有子類(lèi),必須先指定搜索的文件范圍。打個(gè)比方,要尋找一個(gè)古人的所有后代成員,必須設(shè)置查找的地理范圍是在中國(guó)內(nèi),否則就無(wú)從入手。
結(jié)合實(shí)際的項(xiàng)目部署環(huán)境,查找子類(lèi)的方法需要有兩種方式。第一種,在開(kāi)發(fā)環(huán)境,可以直接遍歷指定范圍下的所有源代碼文件,再結(jié)合反射的知識(shí);第二種,假設(shè)項(xiàng)目已經(jīng)打成jar包,則只能通過(guò)jar包獲得所有類(lèi)文件。
下面給出具體的代碼實(shí)現(xiàn)
1.若是開(kāi)發(fā)環(huán)境,則通過(guò)遞歸查找指定目錄下的類(lèi)文件的全路徑,代碼如下
1 /**
2 * 遞歸查找指定目錄下的類(lèi)文件的全路徑3 *4 *@parambaseFile 查找文件的入口5 *@paramfileList 保存已經(jīng)查找到的文件集合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包環(huán)境,則可以通過(guò)JarFile這個(gè)工具類(lèi),獲得所有全部類(lèi)信息
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文件內(nèi)的實(shí)體,即相對(duì)路徑
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.從前兩步可以得到所有子類(lèi)或所有接口實(shí)現(xiàn)類(lèi)的類(lèi)路徑信息,有了類(lèi)的全路徑,就可以通過(guò)反射拿到類(lèi)的信息,用來(lái)判斷是否滿(mǎn)足條件
1 /**
2 * 判斷一個(gè)類(lèi)是否繼承某個(gè)父類(lèi)或?qū)崿F(xiàn)某個(gè)接口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())) {//抽象類(lèi)忽略
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.寫(xiě)幾個(gè)簡(jiǎn)單的測(cè)試類(lèi),用來(lái)說(shuō)明問(wèn)題
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.入口方法,打印輸出結(jié)果(jar包可直接使用Eclipse導(dǎo)出可執(zhí)行jar文件)
1 List fileList = new ArrayList();2
3 File baseFile = new File(getSrcPath() + File.separator + "src" + File.separator + "bean");4 if(baseFile.exists()){//開(kāi)發(fā)環(huán)境,讀取源文件
5 getSubFileNameList(baseFile,fileList);6 }else{//jar包環(huán)境
7 fileList=getClassNameFrom("server.jar");8 }9 System.err.println("Animal類(lèi)的所有子類(lèi)有");10 for(String name:fileList){11 if(isChildClass(name,Animal.class))12 System.err.println(name);13 }
總結(jié)
以上是生活随笔為你收集整理的java 扫描所有子类_java获取全部子类或接口的全部实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java线程不执行_java线程池,阿里
- 下一篇: 暗黑破坏神2重制版亚马逊怎么加点 亚马逊