通过类加载器按包查找
//package com.nowjava; import java.io.File; /*from 时 代 J a v a 公 众 号 - nowjava.com*/ import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.TreeSet; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class Main { public static void main(String[] argv) throws Exception { String packageName = "nowjava.com"; Class isAssignableFrom = String.class;/*时 代 J a v a 公 众 号 - nowjava.com*/ System.out.println(java.util.Arrays.toString(findByPackage( packageName, isAssignableFrom))); } public static Class[] findByPackage(String packageName, Class isAssignableFrom) { Class[] clazzes = getClassesInPackage(packageName, null); if (isAssignableFrom == null) { return clazzes; } else { List<Class> filteredList = new ArrayList<Class>(); for (Class clazz : clazzes) { if (isAssignableFrom.isAssignableFrom(clazz)) filteredList.add(clazz); } return filteredList.toArray(new Class[0]); } } /** * Scans all classes accessible from the context class loader which belong to the given package and subpackages. * Adapted from http://snippets.dzone.com/posts/show/4831 and extended to support use of JAR files * * @param packageName The base package * @param regexFilter an optional class name pattern. * @return The classes */ public static Class[] getClassesInPackage(String packageName, String regexFilter) { Pattern regex = null; if (regexFilter != null) regex = Pattern.compile(regexFilter); try { ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); assert classLoader != null; String path = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); List<String> dirs = new ArrayList<String>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(resource.getFile()); } TreeSet<String> classes = new TreeSet<String>(); for (String directory : dirs) { classes.addAll(findClasses(directory, packageName, regex)); } ArrayList<Class> classList = new ArrayList<Class>(); for (String clazz : classes) { classList.add(Class.forName(clazz)); } return classList.toArray(new Class[classes.size()]); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Recursive method used to find all classes in a given path (directory or zip file url). Directories * are searched recursively. (zip files are * Adapted from http://snippets.dzone.com/posts/show/4831 and extended to support use of JAR files * * @param path The base directory or url from which to search. * @param packageName The package name for classes found inside the base directory * @param regex an optional class name pattern. e.g. .*Test * @return The classes */ private static TreeSet<String> findClasses(String path, String packageName, Pattern regex) throws Exception { TreeSet<String> classes = new TreeSet<String>(); if (path.startsWith("file:") && path.contains("!")) { String[] split = path.split("!"); URL jar = new URL(split[0]); ZipInputStream zip = new ZipInputStream(jar.openStream()); ZipEntry entry; while ((entry = zip.getNextEntry()) != null) { if (entry.getName().endsWith(".class")) { String className = entry.getName() .replaceAll("[$].*", "") .replaceAll("[.]class", "").replace('/', '.'); if (className.startsWith(packageName) && (regex == null || regex.matcher(className) .matches())) classes.add(className); } } } File dir =