集册 Java实例教程 尝试列出由上下文类加载器确定的指定包中的所有类

尝试列出由上下文类加载器确定的指定包中的所有类

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

453
尝试列出由上下文类加载器确定的指定包中的所有类

/*

 * NOTE: This is added by intellij IDE. Disregard this message if there is another copyright later in the file.

 * Copyright (C) 2014-2015  Will (n9Mtq4) Bresnahan

 * This program is free software: you can redistribute it and/or modify

 * it under the terms of the GNU General Public License as published by

 * the Free Software Foundation, either version 3 of the License, or

 * (at your option) any later version

 * This program is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 * GNU General Public License for more details

 * You should have received a copy of the GNU General Public License

 * along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

//package com.nowjava;

import sun.net.www.protocol.file.FileURLConnection;

import java.io.File;
/* 
*来 自
 时 代 J a v a 公 众 号 - N o w J a v  a . c o m
*/

import java.io.IOException;

import java.io.UnsupportedEncodingException;


import java.net.JarURLConnection;

import java.net.URL;

import java.net.URLConnection;

import java.net.URLDecoder;

import java.util.ArrayList;

import java.util.Enumeration;


import java.util.jar.JarEntry;/** N o w  J a v a  .   c o m 提 供 **/

import java.util.jar.JarFile;


public class Main {

    /**

     * Attempts to list all the classes in the specified package as determined

     * by the context class loader

     *

     * @param pckgname the package name to search

     * @return a list of classes that exist within that package

     * @throws ClassNotFoundException if something went wrong

     */

    public static ArrayList<Class<?>> getClassesForPackage(String pckgname)

            throws ClassNotFoundException {

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


        try {

            final ClassLoader cld = Thread.currentThread()

                    .getContextClassLoader();


            if (cld == null)

                throw new ClassNotFoundException("Can't get class loader.");


            Enumeration<URL> resources = cld.getResources(pckgname.replace(

                    '.', '/'));

            URLConnection connection;


            for (URL url = null; resources.hasMoreElements()

                    && ((url = resources.nextElement()) != null);) {

                try {

                    connection = url.openConnection();


                    if (connection instanceof JarURLConnection) {


                        checkJarFile((JarURLConnection) connection,

                                pckgname, classes);


                    } else if (connection instanceof FileURLConnection) {


                        try {

                            checkDirectory(

                                    new File(URLDecoder.decode(

                                            url.getPath(), "UTF-8")),

                                    pckgname, classes);

                        } catch (UnsupportedEncodingException ex) {

                            throw new ClassNotFoundException(

                                    pckgname

                                            + " does not appear to be a valid package (Unsupported encoding)",

                                    ex);

                        }


                    } else

                        throw new ClassNotFoundException(pckgname + " ("

                                + url.getPath()

                                + ") does not appear to be a valid package");

                } catch (final IOException ioex) {

                    throw new ClassNotFoundException(

                            "IOException was thrown when trying to get all resources for "

                                    + pckgname, ioex);

                }

            }

        } catch (final NullPointerException ex) {

            throw new ClassNotFoundException(

                    pckgname

                            + " does not appear to be a valid package (Null pointer exception)",

                    ex);

        } catch (final IOException ioex) {

            throw new ClassNotFoundException(

                    "IOException was thrown when trying to get all resources for "

                            + pckgname, ioex);

        }


        return classes;

    }


    /**

     * Private helper method.

     *

     * @param connection the connection to the jar

     * @param pckgname   the package name to search for

     * @param classes    the current ArrayList of all classes. This method will simply

     *                   add new classes.

     * @throws ClassNotFoundException if a file isn't loaded but still is in the jar file

     * @throws IOException            if it can't correctly read from the jar file.

     */

    private static void checkJarFile(JarURLConnection connection,

            String pckgname, ArrayList<Class<?>> classes)

            throws ClassNotFoundException, IOException {

        final JarFile jarFile = connection.getJarFile();

        final Enumeration<JarEntry> entries = jarFile.entries();

        String name;


        for (JarEntry jarEntry = null; entries.hasMoreElements()

                && ((jarEntry = entries.nextElement()) != null);) {

            name = jarEntry.getName();


            if (name.contains(".class")) {

                name = name.substring(0, name.length() - 6).replace('/',

                        '.');


                if (name.contains(pckgname)) {

                    classes.add(Class.forName(name));

                }

            }

        }

    }


    /**

     * Private helper method

     *

     * @param directory The directory to start with

     * @param pckgname  The package name to search for. Will be needed for getting the

     *                  Class object.

     * @param classes   if a file isn't loaded but still is in the directory

     * @throws ClassNotFoundException

     */

    
展开阅读全文