遍历当前线程的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