java获取全部子类或接口的全部实现
在JAVA中,获取一个类的全部父类是比较简单的,只需要通过反射(Class的getSuperclass()方法)即可。然而,如果想获得一个类的所有子类,或者获得实现某一个接口的所有实现类,相对比较麻烦。
用过Eclipse的开发人员都知道,通过F4键或(Ctrl+T组合键)可以查到指定类的类层次结构。仔细想一下该快捷键的实现原理,或许可以找到一个可行的设计思路。
首先,需要确定一个前提是,寻找所有子类,必须先指定搜索的文件范围。打个比方,要寻找一个古人的所有后代成员,必须设置查找的地理范围是在中国内,否则就无从入手。
结合实际的项目部署环境,查找子类的方法需要有两种方式。第一种,在开发环境,可以直接遍历指定范围下的所有源代码文件,再结合反射的知识;第二种,假设项目已经打成jar包,则只能通过jar包获得所有类文件。
下面给出具体的代码实现
1.若是开发环境,则通过递归查找指定目录下的类文件的全路径,代码如下
/**
* 递归查找指定目录下的类文件的全路径
*
* @param baseFile 查找文件的入口
* @param fileList 保存已经查找到的文件集合
*/
public static void getSubFileNameList(File baseFile, List<String> fileList) {
if (baseFile.isDirectory()) {
File[] files = baseFile.listFiles();
for (File tmpFile : files) {
getSubFileNameList(tmpFile, fileList);
}
}
String path = baseFile.getPath();
if (path.endsWith(".java")) {
String name1 = path.substring(path.indexOf("src") + 4, path.length());
String name2 = name1.replaceAll("\\\\", ".");
String name3 = name2.substring(0, name2.lastIndexOf(".java"));
fileList.add(name3);
}
}
获取根路径方法 final static File rootFolder = new File(SuperClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
2.若是jar包环境,则可以通过JarFile这个工具类,获得所有全部类信息
/**
* 从jar包读取所有的class文件名
*/
private static List<String> getClassNameFrom(String jarName) {
List<String> fileList = new ArrayList<String>();
try {
JarFile jarFile = new JarFile(new File(jarName));
Enumeration<JarEntry> en = jarFile.entries(); // 枚举获得JAR文件内的实体,即相对路径
while (en.hasMoreElements()) {
String name1 = en.nextElement().getName();
if (!name1.endsWith(".class")) {//不是class文件
continue;
}
String name2 = name1.substring(0, name1.lastIndexOf(".class"));
String name3 = name2.replaceAll("/", ".");
fileList.add(name3);
}
} catch (IOException e) {
e.printStackTrace();
} return fileList;
}
3.从前两步可以得到所有子类或所有接口实现类的类路径信息,有了类的全路径,就可以通过反射拿到类的信息,用来判断是否满足条件
/**
* 判断一个类是否继承某个父类或实现某个接口
*/
public static boolean isChildClass(String className, Class parentClazz) {
if (className == null) return false; Class clazz = null;
try {
clazz = Class.forName(className);
if (Modifier.isAbstract(clazz.getModifiers())) {//抽象类忽略
return false;
}
if (Modifier.isInterface(clazz.getModifiers())) {//接口忽略
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return parentClazz.isAssignableFrom(clazz); }
4.写几个简单的测试类,用来说明问题
package bean;
public abstract class Animal {
public abstract void eat();
public abstract void walk();
}
package bean;
public class Cat extends Animal{
@Override
public void eat() {
System.err.println("小猫吃东西");
}
@Override
public void walk() {
System.err.println("小猫走路");
}
}
package bean;
public class Dog extends Animal{
@Override
public void eat() {
System.err.println("小狗吃东西");
}
@Override
public void walk() {
System.err.println("小狗走路");
}
}
package bean;
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void sayHello(){
System.err.println("hello,i am " + this.name);
}
}
5.入口方法,打印输出结果(jar包可直接使用Eclipse导出可执行jar文件)
List<String> fileList = new ArrayList<String>();
File baseFile = new File(getSrcPath() + File.separator + "src" + File.separator + "bean");
if(baseFile.exists()){//开发环境,读取源文件
getSubFileNameList(baseFile,fileList);
}else{//jar包环境
fileList=getClassNameFrom("server.jar");
}
System.err.println("Animal类的所有子类有");
for(String name:fileList){
if(isChildClass(name,Animal.class))
System.err.println(name);
}
java获取全部子类或接口的全部实现的更多相关文章
- Java 获取所有子类信息
我以前的博客(Java Scala获取注解的类信息)介绍过通过Reflections工具通过使用特定注解的类的信息,其实本工具也可以获取接口,抽象类,类等的所有子类信息.使用方法如下: Reflect ...
- java获取https网站证书,附带调用https:webservice接口
一.java 获取https网站证书: 1.创建一个java工程,新建InstallCert类,将以下代码复制进去 package com; import java.io.BufferedReader ...
- Java开发知识之Java中的集合Set接口以及子类应用
---恢复内容开始--- Java开发知识之Java中的集合Set接口以及子类应用 一丶Set接口以及作用 在上一讲.我们熟悉了接口的实现图.以及自己各有的子类. List接口主要存储的数据是可以重复 ...
- Java多线程和并发(四),线程返回值获取方式和Callable接口
目录 1.主线程等待法 2.使用Thread类的join()阻塞当前线程,等待子线程执行完毕 3.通过Callable接口实现:通过FutureTask Or线程池获取 四.线程返回值获取方式和Cal ...
- Java集合框架之Collection接口
Java是一门面向对象的语言,那么我们写程序的时候最经常操作的便是对象了,为此,Java提供了一些专门用来处理对象的类库,这些类库的集合我们称之为集合框架.Java集合工具包位于Java.util包下 ...
- 黑马程序员——JAVA基础之抽象和接口 , 模版方法设计模式
------- android培训.java培训.期待与您交流! ---------- 抽象定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来. 例如:狼 ...
- Java 继承、抽象、接口
一.继承 1. 概述 继承是面向对象的重要特征之一,当多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那多个类中无需再定义这些属性和行为,只需继承那个单独的类即可. 单独的类称为父类或超 ...
- java获取泛型信息
总结一下java中获取与泛型相关的信息的知识,不如说是使用方法.网上也有很多类似的优秀文章,这里主要做一个知识的总结.通过反射获取泛型信息的常见例子: //bean package testProje ...
- java 集合框架(二)Iterable接口
Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...
随机推荐
- SQL 必知必会笔记--完整介绍sql技巧
PS:完整介绍数据处理,表结构操作,视图,事务处理,存储过程,约束,索引,游标,触发,数据库安全等sql技巧 目录 数据处理 增:插入数据+复制表 删:删除行数据+删除指定列数据 改:更新数据 查:基 ...
- service worker(二)之主页面与service worker通信
实现一个主页面发送消息,worker搜到信息向所有的页面派发消息(当前页面除外) msg.html <!DOCTYPE html> <html lang="en" ...
- restful接口规范 | 基于restful的原生django接口
restful接口规范 接口 接口:联系两个物质的媒介,完成信息交互 web程序中:联系前台页面与后台数据库的媒介 web接口组成: - url:长得像返回数据的url链接 - 请求参数:前台按照指定 ...
- PostgreSQL 输出 JSON 结果
PostGreSQL 从 9.2 开始增加对 JSON 的支持.9.5 已经支持多个 JSON 函数,见 http://www.postgres.cn/docs/9.5/functions-json. ...
- 014_Python3 循环语句
1.while 循环 #!/usr/bin/env python3 n = 100 sum = 0 counter = 1 while counter <= n: sum = s ...
- Linux中三种SCSI target的介绍之LIO
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/scaleqiao/article/deta ...
- PHP-FPM 的工作整理
1.php-fpm的配置文件 根据命令找到路径修改配置文件 ps -ef|grep php-fpm vim /home/php/etc/php-fpm.conf ;;;;;;;;;;;;;;;;;; ...
- Pytorch在colab和kaggle中使用TensorBoard/TensorboardX可视化
在colab和kaggle内核的Jupyter notebook中如何可视化深度学习模型的参数对于我们分析模型具有很大的意义,相比tensorflow, pytorch缺乏一些的可视化生态包,但是幸好 ...
- 查看windows操作系统的默认编码【转】
在Windows平台下,进入DOS窗口,输入:chcp可以得到操作系统的代码页信息,你可以从控制面板的语言选项中查看代码页对应的详细的字符集信息. 例如: 我的活动代码页为:936,它对于的编码格式为 ...
- java读取文件内容并输出到控制台,java中实现文件复制
public class TestFileInputStream { public static void main(String [] args) { //读取指定文件中内容,并在控制台输出 Fil ...