JAvaはパケット名反射によりすべてのクラス名を取得する

5642 ワード

プログラミングでは、パケットの下にあるすべてのクラス名を取得する必要があります.反射によって実現されます.
方法は次のとおりです.
 
/**
 *               
 *
 * @param pack
 * @return
 * @throws Exception
 */
public static Set> getClasses(String pack) throws Exception {

    //    class    
    Set> classes = new LinkedHashSet>();
    //       
    boolean recursive = true;
    //             
    String packageName = pack;
    String packageDirName = packageName.replace('.', '/');
    //                         things
    Enumeration dirs;
    try {
        dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
        //       
        while (dirs.hasMoreElements()) {
            //        
            URL url = dirs.nextElement();
            //        
            String protocol = url.getProtocol();
            //                 
            if (StringUtil.equals("file", protocol)) {
                //         
                String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                //                        
                findClassesInPackageByFile(packageName, filePath, recursive, classes);
            } else if (StringUtil.equals("jar", protocol)) {
                //    jar   
                //     JarFile
                System.out.println("jar     ");
                JarFile jar;
                try {
                    //   jar
                    jar = ((JarURLConnection) url.openConnection()).getJarFile();
                    //   jar         
                    Enumeration entries = jar.entries();
                    findClassesInPackageByJar(packageName, entries, packageDirName, recursive, classes);
                } catch (IOException e) {
                    // log.error("           jar       ");
                    e.printStackTrace();
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return classes;
}

/**
 *  jar           Class
 *
 * @param packageName
 * @param entries
 * @param packageDirName
 * @param recursive
 * @param classes
 */
private static void findClassesInPackageByJar(String packageName, Enumeration entries, String packageDirName, final boolean recursive, Set> classes) {
    //          
    while (entries.hasMoreElements()) {
        //   jar                jar         META-INF   
        JarEntry entry = entries.nextElement();
        String name = entry.getName();
        //     /   
        if (name.charAt(0) == '/') {
            //         
            name = name.substring(1);
        }
        //               
        if (name.startsWith(packageDirName)) {
            int idx = name.lastIndexOf('/');
            //    "/"       
            if (idx != -1) {
                //       "/"   "."
                packageName = name.substring(0, idx).replace('/', '.');
            }
            //                
            if ((idx != -1) || recursive) {
                //      .class         
                if (name.endsWith(".class") && !entry.isDirectory()) {
                    //      ".class"        
                    String className = name.substring(packageName.length() + 1, name.length() - 6);
                    try {
                        //    classes
                        classes.add(Class.forName(packageName + '.' + className));
                    } catch (ClassNotFoundException e) {
                        // .error("                   .class  ");
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

/**
 *               Class
 *
 * @param packageName
 * @param packagePath
 * @param recursive
 * @param classes
 */
private static void findClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, Set> classes) {
    //             File
    File dir = new File(packagePath);
    //                   
    if (!dir.exists() || !dir.isDirectory()) {
        // log.warn("       " + packageName + "        ");
        return;
    }
    //                     
    File[] dirfiles = dir.listFiles(new FileFilter() {
        //               (     )     .class     (    java   )
        @Override
        public boolean accept(File file) {
            return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
        }
    });
    //       
    for (File file : dirfiles) {
        //            
        if (file.isDirectory()) {
            findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
        } else {
            //    java         .class      
            String className = file.getName().substring(0, file.getName().length() - 6);
            try {
                //        
                // classes.add(Class.forName(packageName + '.' +
                // className));
                //          ,   forName     ,   static  ,    classLoader load  
                classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
            } catch (ClassNotFoundException e) {
                // log.error("                   .class  ");
                e.printStackTrace();
            }
        }
    }
}

パケット名を入力すると、現在のパケット名の下にあるクラス名が得られます.