java使用反射动态的获取接口的所有实现类并实例化(非抽象类)

实现的功能的业务是这样的,动态的获取java接口的所有的实现类并且排除抽象类和接口本身。

代码实现

1.创建接口Animal

package com.tcp.executor;
public interface Animal {

    public void say();

}

2.创建抽象类实现Animal

package com.tcp.executor;
public abstract class AbstractAnimal implements Animal {

    public void sleep(){
        System.out.println("睡觉了");
    }
}

3.创建实现类Cat继承抽象类

package com.tcp.executor;
public class Cat extends AbstractAnimal {

    @Override
    public void say() {
        System.out.println("我是猫");
    }
}

4.创建实现类Chicken继承抽象类

package com.tcp.executor;
public class Chicken extends AbstractAnimal {
    @Override
    public void say() {
        System.out.println("我是鸡");
    }
}

5.创建实现类Lion继承抽象类

package com.tcp.executor;
public class Lion extends AbstractAnimal {
    @Override
    public void say() {
        System.out.println("我是狮子");
    }
}

6.创建实现类Tiger继承抽象类

package com.tcp.executor;
public class Tiger extends AbstractAnimal {
    @Override
    public void say() {
        System.out.println("我是老虎");
    }
}

7.创建实现类Dog继承抽象类

package com.tcp.executor;
public class Dog extends AbstractAnimal {

    @Override
    public void say() {
        System.out.println("我是狗");
    }
}

测试代码

package com.tcp.executor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class Demo {

    public static void main(String[] args) throws Exception {
        List<Animal> animals = new ArrayList<>();
        List<Class> clazzs = getAllInterfaceAchieveClass(Animal.class);
        for(Class clazz : clazzs){
           animals.add((Animal)clazz.newInstance());
        }
        //打印Class对象
        for(Animal cla : animals){
            System.out.println("实现类:"+cla.getClass());
        }
    }

    /**
     * 获取所有接口的实现类
     * @return
     */
    public static List<Class> getAllInterfaceAchieveClass(Class clazz){
        ArrayList<Class> list = new ArrayList<>();
        //判断是否是接口
        if (clazz.isInterface()) {
            try {
                ArrayList<Class> allClass = getAllClassByPath(clazz.getPackage().getName());
                /**
                 * 循环判断路径下的所有类是否实现了指定的接口
                 * 并且排除接口类自己
                 */
                for (int i = 0; i < allClass.size(); i++) {

                    //排除抽象类
                    if(Modifier.isAbstract(allClass.get(i).getModifiers())){
                        continue;
                    }
                    //判断是不是同一个接口
                    if (clazz.isAssignableFrom(allClass.get(i))) {
                        if (!clazz.equals(allClass.get(i))) {
                            list.add(allClass.get(i));
                        }
                    }
                }
            } catch (Exception e) {
                System.out.println("出现异常");
            }
        }
        return list;
    }

    /**
     * 从指定路径下获取所有类
     * @return
     */
    public static ArrayList<Class> getAllClassByPath(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(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
     */
    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 {
                    //保存的类文件不需要后缀.class
                    list.add(Class.forName(packagename + '.' + file2.getName().substring(0,
                            file2.getName().length()-6)));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }
}

运行结果

在这里插入图片描述
以上代码都测试过。

发布了60 篇原创文章 · 获赞 1 · 访问量 3348

猜你喜欢

转载自blog.csdn.net/qq_16438883/article/details/103408709