Java -- 獲取指定接口的所有實現類或獲取指定類的所有繼承類


Class : ClassUtil

package pri.lime.main;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;

/**
 * 查找指定路徑下面實現指定接口的全部類
 * 
 * @author Liang
 *
 *         2017年5月9日
 */
public class ClassUtil {

    @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:判定此 Class 對象所表示的類或接口與指定的 Class
                    // 參數所表示的類或接口是否相同,或是否是其超類或超接口
                    if (clazz.isAssignableFrom(allClass.get(i))) {
                        if (!clazz.equals(allClass.get(i))) {
                            // 自身並不加進去
                            list.add(allClass.get(i));
                        }
                    }
                }
            } catch (Exception e) {
                System.out.println("出現異常");
            }
        } else {
            // 如果不是接口,則獲取它的所有子類
            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));
                        }
                    }
                }
            } catch (Exception e) {
                System.out.println("出現異常");
            }
        }
        return list;
    }

    /**
     * 從一個指定路徑下查找所有的類
     * 
     * @param name
     */
    @SuppressWarnings("rawtypes")
    private static ArrayList<Class> getAllClass(String packagename) {
        ArrayList<Class> list = new ArrayList<>();
        // 返回對當前正在執行的線程對象的引用。
        // 返回該線程的上下文 ClassLoader。
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        String path = packagename.replace('.', '/');
        try {
            ArrayList<File> fileList = new ArrayList<>();
            /**
             * 這里面的路徑使用的是相對路徑 如果大家在測試的時候獲取不到,請理清目前工程所在的路徑 使用相對路徑更加穩定!
             * 另外,路徑中切不可包含空格、特殊字符等!
             */
            // getResources:查找所有給定名稱的資源
            // 獲取jar包中的實現類:Enumeration<URL> enumeration =
            // classLoader.getResources(path);
            Enumeration<URL> enumeration = classLoader.getResources("../bin/" + path);
            while (enumeration.hasMoreElements()) {
                URL url = enumeration.nextElement();
                // 獲取此 URL 的文件名
                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(".");// 添加斷言用於判斷
                if (!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;
    }
}

啦啦啦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM