天天看點

《設計模式之禅》中根據一個接口查找所有實作類

package designPattern.factoryMethodPattern;

import java.io.File;

import java.io.IOException;

import java.net.URL;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.List;

public class ClassUtils {  

    public static List<Class> getAllClassByInterface(Class c) {  

        // 給一個接口,傳回這個接口的所有實作類  

        List<Class> returnClassList = new ArrayList<Class>();// 傳回結果  

        // 如果不是一個接口,則不做處理  

        if (c.isInterface()) {  

            String packageName = c.getPackage().getName();// 獲得目前包名  

            try {  

                List<Class> allClass = getClasses(packageName);// 獲得目前包下以及包下的所有類  

                for (int i = 0; i < allClass.size(); i++) {  

                    if (c.isAssignableFrom(allClass.get(i))) {// 判斷是不是一個接口  

                        if (!c.equals(allClass.get(i))) {// 本身加不進去  

                            returnClassList.add(allClass.get(i));  

                        }  

                    }  

                }  

            } catch (ClassNotFoundException e) {  

                // TODO Auto-generated catch block  

                e.printStackTrace();  

            } catch (IOException e) {  

                // TODO: handle exception  

                e.printStackTrace();  

            }  

        }  

        return returnClassList;  

    }  

    // 從一個包中查找出所有類,在jar包中不能查找  

    private static List<Class> getClasses(String packageName)  

            throws IOException, ClassNotFoundException {  

        ClassLoader classLoader = Thread.currentThread()  

                .getContextClassLoader();  

        String path = packageName.replace('.', '/');  

        Enumeration<URL> resources = classLoader.getResources(path);  

        List<File> dirs = new ArrayList<File>();  

        while (resources.hasMoreElements()) {  

            URL resource = resources.nextElement();  

            dirs.add(new File(resource.getFile()));  

        }  

        ArrayList<Class> classes = new ArrayList<Class>();  

        for (File directory : dirs) {  

            classes.addAll(findClasses(directory, packageName));  

        }  

        return classes;  

    }  

    private static List<Class> findClasses(File directory, String packageName)  

            throws ClassNotFoundException {  

        List<Class> classes = new ArrayList<Class>();  

        if (!directory.exists()) {  

            return classes;  

        }  

        File[] files = directory.listFiles();  

        for (File file : files) {  

            if (file.isDirectory()) {  

                assert !file.getName().contains(".");  

                classes.addAll(findClasses(file, packageName + '.' 

                        + file.getName()));  

            } else if (file.getName().endsWith(".class")) {  

                classes.add(Class.forName(packageName  

                        + "." 

                        + file.getName().substring(0,  

                                file.getName().length() - 6)));  

            }  

        }  

        return classes;  

    }  

}