获取实现了指定接口类的所有实现类或继承了指定类的所有子类

实际编程过程中,我们可能遇到这样的问题,就是获取实现了指定接口类的所有实现类。 本工具类就提供了这样的功能。下面是工具类的详细解析:

/** * 查找指定路径下面实现指定接口的全部类 * @author longyin * @author 博客地址: * 如果大家有什么问题或疑问,欢迎留言或评论,谢谢!! */{@SuppressWarnings({ “rawtypes”, “unchecked” })public static ArrayList<Class> getAllClassByInterface(Class clazz){ArrayList<Class> list = new ArrayList<>();//判断是否是一个接口if (clazz.isInterface()) {try {ArrayList<Class> allClass = getAllClass(clazz.getPackage().getName());/*** 循环判断路径下的所有类是否实现了指定的接口* 并且排除接口类自己*/for (int i = 0; i < allClass.size(); i++) {/*** 判断是不是同一个接口* 该方法的解析,请参考博客:* */if (clazz.isAssignableFrom(allClass.get(i))) {if (!clazz.equals(allClass.get(i))) {//自身并不加进去list.add(allClass.get(i));}else {}}}} catch (Exception e) {System.out.println(“出现异常”);}}else {//如果不是接口不作处理}return list;}/*** 从一个指定路径下查找所有的类* @param name*/@SuppressWarnings(“rawtypes”)private static ArrayList<Class> getAllClass(String packagename) {ArrayList<Class> list = new ArrayList<>();ClassLoader classLoader = Thread.currentThread().getContextClassLoader();String path = packagename.replace(‘.’, ‘/’);try {ArrayList<File> fileList = new ArrayList<>();/*** 这里面的路径使用的是相对路径* 如果大家在测试的时候获取不到,请理清目前工程所在的路径* 使用相对路径更加稳定!* 另外,路径中切不可包含空格、特殊字符等!* 本人在测试过程中由于空格,吃了大亏!!!*/Enumeration<URL> enumeration = classLoader.getResources(“../bin/”+path);while (enumeration.hasMoreElements()) {URL url = enumeration.nextElement();fileList.add(new File(url.getFile()));}for (int i = 0; i < fileList.size(); i++) {list.addAll(findClass(fileList.get(i),packagename));}} catch (IOException e) {e.printStackTrace();}return list;}/*** 如果file是文件夹,,则递归调用findClass方法,或者文件夹下的类* 如果file本身是类文件,则加入list中进行保存,并返回* @param file* @param packagename* @return*/@SuppressWarnings(“rawtypes”)private static ArrayList<Class> findClass(File file,String packagename) {ArrayList<Class> list = new ArrayList<>();if (!file.exists()) {return list;}File[] files = file.listFiles();for (File file2 : files) {if (file2.isDirectory()) {assert !file2.getName().contains(“.”);//添加断言用于判断ArrayList<Class> arrayList = findClass(file2, packagename+”.”+file2.getName());list.addAll(arrayList);}else if(file2.getName().endsWith(“.class”)){try {//保存的类文件不需要后缀.classlist.add(Class.forName(packagename + ‘.’ + file2.getName().substring(0,file2.getName().length()-6)));} catch (ClassNotFoundException e) {e.printStackTrace();}}}return list;}}

上面方法,大家在运行测试的时候一定记得更改路径。一定以当前功能文件所在的路径下使用相对路径进行更新,是路径执行可执行的.class文件。 上面的类中的public方法是提供给外界进行调用的,该方法里面有一个isInterface的判断,加入了该判断的话,就只能获取所有实现了指定接口的类,那么要获取继承了指定类的所有类怎么做呢? 非常简单,不加这个判断就可以了。 所有上面的public方法更改如下:

@SuppressWarnings({ “rawtypes”, “unchecked” })public static ArrayList<Class> getAllClassByInterface(Class clazz){ArrayList<Class> list = new ArrayList<>();//获取指定接口的实现类if (clazz.isInterface()) {try {ArrayList<Class> allClass = getAllClass(clazz.getPackage().getName());/*** 循环判断路径下的所有类是否实现了指定的接口* 并且排除接口类自己*/for (int i = 0; i < allClass.size(); i++) {/*** 判断是不是同一个接口* isAssignableFrom该方法的解析,请参考博客:* */if (clazz.isAssignableFrom(allClass.get(i))) {if (!clazz.equals(allClass.get(i))) {//自身并不加进去list.add(allClass.get(i));}else {}}}} catch (Exception e) {System.out.println(“出现异常”);}//如果不是接口,则获取它的所有子类}else{try {ArrayList<Class> allClass = getAllClass(clazz.getPackage().getName());/*** 循环判断路径下的所有类是否继承了指定类* 并且排除父类自己*/for (int i = 0; i < allClass.size(); i++) {/*** isAssignableFrom该方法的解析,请参考博客:* */if (clazz.isAssignableFrom(allClass.get(i))) {if (!clazz.equals(allClass.get(i))) {//自身并不加进去list.add(allClass.get(i));}else {}}}} catch (Exception e) {System.out.println(“出现异常”);}}return list;}

在else中可以获取到所有继承了指定类的所有子类!!!

本人测试完成,完全满足需求!!! 如果有疑问,请留言或评论!!

他们的快乐像贪玩的小孩,游荡到天光却还不肯回来。

获取实现了指定接口类的所有实现类或继承了指定类的所有子类

相关文章:

你感兴趣的文章:

标签云: