集册 Java实例教程 遍历当前线程的ClassLoader中的所有资源并搜索.class文件,然后尝试从文件名中解析类名称,并找到Class对象。

遍历当前线程的ClassLoader中的所有资源并搜索.class文件,然后尝试从文件名中解析类名称,并找到Class对象。

欢马劈雪     最近更新时间:2020-01-02 10:19:05

944
遍历当前线程的ClassLoader中的所有资源并搜索.class文件,然后尝试从文件名中解析类名称,并找到Class对象。


//package com.nowjava;

import java.io.File;

import java.io.IOException;
/*来自 
 n o w j a v a . c o m - 时代Java*/

import java.lang.reflect.Modifier;

import java.net.JarURLConnection;

import java.net.URL;

import java.net.URLDecoder;

import java.util.Collections;

import java.util.HashSet;

import java.util.Set;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;


public class Main {


    /**

     * Iterates through all resources in current thread's <code>ClassLoader</code> and searches for

     * <i>.class</i> files, then attempts to parse the class name from file name, and find the 

     * <code>Class</code> object. <br>

     * Searches only through <i>.jar</i> files and extracted <i>.class</i> files, so, for example, 

     * it can't search the java.* package.

     * 

     * @param packageName search in this package

     * @return <code>Set</code> of found <code>Class</code> objects

     * @throws IOException

     */

    public static Set<Class<?>> getAllClasses(String packageName)

            throws IOException {

        Set<Class<?>> classes = new HashSet<Class<?>>();

        /**来自 
         时代Java - N o w  J a v a . c o m**/

        if (packageName == null || packageName.length() == 0) {

            return classes;

        }


        for (URL resource : Collections.list(getClassLoader().getResources(

                packageName.replace('.', '/')))) {

            if (resource.getProtocol().equalsIgnoreCase("jar")) {

                classes.addAll(getClassesInJarResource(resource,

                        packageName));

            } else if (resource.getProtocol().equalsIgnoreCase("file")) {

                classes.addAll(getClassesInFileResource(

                        new File(URLDecoder.decode(resource.getPath(),

                                "UTF-8")), packageName));

            }

        }


        return classes;

    }


    private static ClassLoader getClassLoader() {

        return Thread.currentThread().getContextClassLoader();

    }


    private static Set<Class<?>> getClassesInJarResource(URL resource,

            String packageName) throws IOException {

        Set<Class<?>> classes = new HashSet<Class<?>>();


        JarURLConnection conn = (JarURLConnection) resource

                .openConnection();

        JarFile jar = conn.getJarFile();


        for (JarEntry entry : Collections.list(jar.entries())) {

            String n = entry.getName();

            if (n.startsWith(packageName.replace('.', '/'))

                    && n.endsWith(".class")) {

                if (n.contains("$")) {

                    if (isAnonymous(n)) {

                        return classes;

                    }

                }

                String className = n.replace("/", ".").substring(0,

                        n.length() - 6);

                try {

                    Class<?> klass = getClassForName(className);

                    if (!Modifier.isPrivate(klass.getModifiers())) {

                        classes.add(klass);

                    }

                } catch (ClassNotFoundException e) {

                    //

                }

            }

        }


        return classes;

    }


    private static Set<Class<?>> getClassesInFileResource(File file,

            String packageName) throws IOException {

        Set<Class<?>> classes = new HashSet<Class<?>>();


        if (file.exists()) {

            if (file.isDirectory()) {

                for (File f : file.listFiles()) {

                    classes.addAll(getClassesInFileResource(f, packageName));

                }

            } else {

                String fileName = file.getAbsolutePath();

                if (fileName.endsWith(".class")) {

                    if (fileName.contains("$")) {

                        String innerName = fileName.substring(

                                fileName.lastIndexOf("$") + 1,

                                fileName.lastIndexOf("."));

                        if (isAnonymous(innerName)) {

                            // Ignore anonymous inner classes

                            return classes;

                        }

                    }

                    // removes the .class extension

                    fileName = fileName.substring(0, fileName.length() - 6);

                    fileName = fileName.replace(getSystemFileSeperator(),

                            ".");

                    fileName = fileName.substring(fileName

                            .indexOf(packageName));


                    try {

                        Class<?> klass = getClassForName(fileName);

                        if (!Modifier.isPrivate(klass.getModifiers())) {

                            classes.add(klass);

                        }

                    } catch (ClassNotFoundException e) {

                        //

                    }

                }

            }

        }


        return classes;

    }


    private static boolean isAnonymous(String className) {

        return className.matches("\\d*");

    }


    private 
展开阅读全文