在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获取全部子类或接口的全部实现相关推荐

  1. Java 扫描枚举类并获取属性

    Java 扫描枚举类并获取属性 文章目录 Java 扫描枚举类并获取属性 第一步:在 pom.xml 下导入 hutool 和 commons-lang3 第二步:写一个接口以规范枚举的属性 第三步: ...

  2. java超类 子类_Java超类引用子类对象的规律

    首先,对于JVM实现引用的一个机制是:类实例的引用就是指向一个句柄(handle)的指针,这个句柄就是一堆指针:一个指针指向一块从java堆中为分配出来内存空间:另一个指针指向一张表(实际上这个表格也 ...

  3. java 获取秒数_Java获取精确到秒的时间戳(转)

    1.时间戳简介: 时间戳的定义:通常是一个字符序列,唯一地标识某一刻的时间.数字时间戳技术是数字签名技术一种变种的应用.是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01 ...

  4. java什么是子类_java什么是子类?

    java中子类的定义为在有继承关系的类中extends前面的类则是子类.[推荐学习:java课程] 继承,是对有着共同特性的多类事物,进行再抽象成一个类.这个类就是多类事物的父类.父类的意义在于可以抽 ...

  5. java+switch语句+枚举_Java:在子类下使用带有枚举的switch语句

    Java:在子类下使用带有枚举的switch语句 首先,我将说明我对C#中的枚举更加熟悉,看起来java中的枚举非常混乱. 正如您所看到的,我正在尝试在下一个示例中使用switch语句@enums,但 ...

  6. java子类的子类_java中的子类是什么

    java中的子类是什么 发布时间:2020-06-26 15:57:41 来源:亿速云 阅读:152 作者:Leah java中的子类是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编 ...

  7. java中的随机数_Java获取随机数

    随机数在实际中使用很广泛,比如要随即生成一个固定长度的字符串.数字.或者随即生成一个不定长度的数字.或者进行一个模拟的随机选择等等.Java提供了最基本的工具,可以帮助开发者来实现这一切. 一.Jav ...

  8. java windows wifi密码_java 获取本机连接过的所有WiFI密码

    windows,cmd中可以通过命令行输入指令: netsh wlan show profiles 来获取连接过的WiFi名: 然后可以输入命令:获取WiFi名为 哦 的个密码 netsh wlan ...

  9. java 文件md5校验_Java 获取 文件md5校验码

    讯雷下载的核心思想是校验文件的md5值,两个文件若md5相同则为同一文件. 当得到用户下载某个文件的请求后它根据数据库中保留的文件md5比对出拥有此文件的url, 将用户请求挂接到此url上并仿造一个 ...

最新文章

  1. postgresql学习笔记(三)连接管理
  2. GM6 1.38.1 start up debug - share memory
  3. 【LINUX学习】链接文件
  4. 使用matlab内存不足,Matlab内存不足问题(Out of memory)
  5. mysql大数据量使用limit分页,随着页码的增大,查询效率越低下。
  6. BZOJ.1178.[APIO2009]会议中心(贪心 倍增)
  7. 二叉树层次遍历--广度遍历和深度遍历
  8. WPF 引用 ttf文件
  9. 交通信息工程 实验四:交通仿真实验(二)
  10. proteus常用器件
  11. 联想台式机进入修复计算机,联想台式机一键恢复的使用方法
  12. 小程序 图片显示模式详解
  13. Flutter插件shared_preferences数据存储的使用
  14. 轻型本地服务器_一小时超轻型漂移机
  15. 【完全信息静态博弈-Nash均衡的特性】
  16. odoo12企业版修改邮箱配置
  17. 最全解读 |《数据安全法(草案)》热点解析(上)
  18. k8s初面考点ReplicaSet副本集极限9连击你懂了吗?
  19. “虎”力全开 | Smartbi收获20+感谢信,豪情满怀迎新春
  20. 吴恩达机器学习(七)矩阵应用于数值预测

热门文章

  1. android复位机器人图片,安卓(Android)新图标!小绿机器人换脸啦
  2. 立体栅格地图_更新丨智图栅格数据—彩色版地图,智臻智美,带来更好的业务体验...
  3. 报错注入_sqli-labs less5 Double Query- Single Quotes- String
  4. 图像拼接c语言,安卓上实现图像拼接(JNI调用NATIVE方法)
  5. 如何降低Windows Server 2008的IE安全级别?
  6. linux 脚本学习--细节问题
  7. 《Inside C#》笔记(二) 初识C#
  8. 内存的使用和优化的注意事项
  9. 1289 大鱼吃小鱼
  10. ArcGIS网络分析之Silverlight客户端最近设施点分析(四)