你能用reflectionfind一个包里的所有类吗?

是否有可能find给定包中的所有类或接口? (快速看例如Package ,这似乎是不。)

由于类装载机的dynamic特性,这是不可能的。 类加载器不需要告诉虚拟机可以提供哪些类,而只是递交类的请求,而不得不返回类或抛出exception。

但是,如果您编写自己的类加载器,或者检查类path和它的jar,可以find这些信息。 这将通过文件系统操作,而不是reflection。 甚至可能有图书馆可以帮助你做到这一点。

如果有类生成,或远程传递,你将无法发现这些类。

正常的方法是在某个地方注册你需要访问的类在一个文件中,或引用他们在不同的类。 或者只是使用惯例,当谈到命名。

附录: Reflections Library允许您在当前类path中查找类。 它可以用来获取包中的所有类:

  Reflections reflections = new Reflections("my.project.prefix"); Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class); 

你应该看看开源的reflection库 。 有了它,你可以轻松实现你想要的。

首先,设置reflection索引(这是有点麻烦,因为search所有类是默认禁用):

 List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>(); classLoadersList.add(ClasspathHelper.contextClassLoader()); classLoadersList.add(ClasspathHelper.staticClassLoader()); Reflections reflections = new Reflections(new ConfigurationBuilder() .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))) .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("org.your.package")))); 

然后你可以查询给定包中的所有对象:

 Set<Class<?>> classes = reflections.getSubTypesOf(Object.class); 

Google Guava 14包含了一个新的ClassPath有三种扫描顶级类的方法:

  • getTopLevelClasses()
  • getTopLevelClasses(String packageName)
  • getTopLevelClassesRecursive(String packageName)

有关更多信息,请参阅ClassPath javadocs 。

  /** * Scans all classes accessible from the context class loader which belong to the given package and subpackages. * * @param packageName The base package * @return The classes * @throws ClassNotFoundException * @throws IOException */ private static Class[] getClasses(String packageName) throws ClassNotFoundException, IOException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); assert classLoader != null; String path = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); List<File> dirs = new ArrayList<File>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(new File(resource.getFile())); } ArrayList<Class> classes = new ArrayList<Class>(); for (File directory : dirs) { classes.addAll(findClasses(directory, packageName)); } return classes.toArray(new Class[classes.size()]); } /** * Recursive method used to find all classes in a given directory and subdirs. * * @param directory The base directory * @param packageName The package name for classes found inside the base directory * @return The classes * @throws ClassNotFoundException */ private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException { List<Class> classes = new ArrayList<Class>(); if (!directory.exists()) { return classes; } File[] files = directory.listFiles(); for (File file : files) { if (file.isDirectory()) { assert !file.getName().contains("."); classes.addAll(findClasses(file, packageName + "." + file.getName())); } else if (file.getName().endsWith(".class")) { classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); } } return classes; } 

弹簧

这个例子是针对Spring 4的,但是你也可以在早期版本中find类path扫描器。

 // create scanner and disable default filters (that is the 'false' argument) final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); // add include filters which matches all the classes (or use your own) provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*"))); // get matching classes defined in the package final Set<BeanDefinition> classes = provider.findCandidateComponents("my.package.name"); // this is how you can load the class type from BeanDefinition instance for (BeanDefinition bean: classes) { Class<?> clazz = Class.forName(bean.getBeanClassName()); // ... do your magic with the class ... } 

Google Guava

注意:在版本14中,API仍被标记为@Beta ,因此请留意生产代码。

 final ClassLoader loader = Thread.currentThread().getContextClassLoader(); for (final ClassPath.ClassInfo info : ClassPath.from(loader).getTopLevelClasses()) { if (info.getName().startsWith("my.package.")) { final Class<?> clazz = info.load(); // do something with your clazz } } 

你好。 我总是有上述解决scheme(和其他网站)的一些问题。
作为一名开发人员,我正在编写一个API插件。 API允许使用任何外部库或第三方工具。 该设置还包含jar或zip文件中的代码和直接位于某些目录中的类文件的混合。 所以我的代码必须能够在每个设置周围工作。 经过大量的研究,我提出了一种方法,至less可以在所有可能的设置中使用95%。

下面的代码基本上是总是有效的矫枉过正的方法。

代码:

此代码扫描包含在其中的所有类的给定包。 它只适用于当前ClassLoader中的所有类。

 /** * 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 */ private static void checkDirectory(File directory, String pckgname, ArrayList<Class<?>> classes) throws ClassNotFoundException { File tmpDirectory; if (directory.exists() && directory.isDirectory()) { final String[] files = directory.list(); for (final String file : files) { if (file.endsWith(".class")) { try { classes.add(Class.forName(pckgname + '.' + file.substring(0, file.length() - 6))); } catch (final NoClassDefFoundError e) { // do nothing. this class hasn't been found by the // loader, and we don't care. } } else if ((tmpDirectory = new File(directory, file)) .isDirectory()) { checkDirectory(tmpDirectory, pckgname + "." + file, 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)); } } } } /** * 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."); final 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 (final 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; } 

这三种方法使您能够查找给定包中的所有类。
你这样使用它:

 getClassesForPackage("package.your.classes.are.in"); 

解释:

该方法首先获取当前的ClassLoader 。 然后它获取包含所述包的所有资源并迭代这些URL 。 然后它创build一个URLConnection并确定我们有什么types的URl。 它可以是目录( FileURLConnection ),也可以是jar或zip文件( JarURLConnection )中的目录。 根据什么types的连接,我们有两种不同的方法将被调用。

首先让我们看看如果它是一个FileURLConnection会发生什么。
它首先检查传递的文件是否存在,并且是一个目录。 如果是这样的话,它会检查它是否是一个类文件。 如果是这样,一个Class对象将被创build并放入ArrayList 。 如果它不是一个类文件,而是一个目录,我们只需要迭代它就可以做同样的事情。 所有其他案件/文件将被忽略。

如果URLConnectionJarURLConnection ,则将调用另一个私有方法。 此方法遍历zip / jar存档中的所有条目。 如果一个条目是一个类文件,并且位于包的内部,则将创build一个Class对象并将其存储在ArrayList

在所有的资源被parsing之后(main方法)返回给定包中所有类的ArrayList ,即当前ClassLoader知道的。

如果进程在任何时候失败,将抛出一个ClassNotFoundExceptionexception,包含有关确切原因的详细信息。

不使用任何额外的库:

 package test; import java.io.DataInputStream; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) throws Exception{ List<Class> classes = getClasses(Test.class.getClassLoader(),"test"); for(Class c:classes){ System.out.println("Class: "+c); } } public static List<Class> getClasses(ClassLoader cl,String pack) throws Exception{ String dottedPackage = pack.replaceAll("[/]", "."); List<Class> classes = new ArrayList<Class>(); URL upackage = cl.getResource(pack); DataInputStream dis = new DataInputStream((InputStream) upackage.getContent()); String line = null; while ((line = dis.readLine()) != null) { if(line.endsWith(".class")) { classes.add(Class.forName(dottedPackage+"."+line.substring(0,line.lastIndexOf('.')))); } } return classes; } } 

通常,类加载器不允许扫描类path中的所有类。 但通常唯一使用的类加载器是UrlClassLoader,我们可以从中检索目录和jar文件的列表(请参阅getURLs ),并逐个打开它们列出可用的类。 这种称为类path扫描的方法在Scannotation和Reflections中实现 。

 Reflections reflections = new Reflections("my.package"); Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class); 

另一种方法是使用Java Pluggable Annotation Processing API来编写注释处理器,该处理器将在编译时收集所有带注释的类,并为运行时使用构build索引文件。 这个机制在ClassIndex库中实现:

 // package-info.java @IndexSubclasses package my.package; // your code Iterable<Class> classes = ClassIndex.getPackageClasses("my.package"); 

请注意,由于Java编译器自动发现类path中find的任何处理器,扫描完全自动化,因此不需要额外的设置。

这是我怎么做的。 我扫描所有的子文件夹(子包),我不尝试加载匿名类:

  /** * Attempts to list all the classes in the specified package as determined * by the context class loader, recursively, avoiding anonymous classes * * @param pckgname * the package name to search * @return a list of classes that exist within that package * @throws ClassNotFoundException * if something went wrong */ private static List<Class> getClassesForPackage(String pckgname) throws ClassNotFoundException { // This will hold a list of directories matching the pckgname. There may be more than one if a package is split over multiple jars/paths ArrayList<File> directories = new ArrayList<File>(); String packageToPath = pckgname.replace('.', '/'); try { ClassLoader cld = Thread.currentThread().getContextClassLoader(); if (cld == null) { throw new ClassNotFoundException("Can't get class loader."); } // Ask for all resources for the packageToPath Enumeration<URL> resources = cld.getResources(packageToPath); while (resources.hasMoreElements()) { directories.add(new File(URLDecoder.decode(resources.nextElement().getPath(), "UTF-8"))); } } catch (NullPointerException x) { throw new ClassNotFoundException(pckgname + " does not appear to be a valid package (Null pointer exception)"); } catch (UnsupportedEncodingException encex) { throw new ClassNotFoundException(pckgname + " does not appear to be a valid package (Unsupported encoding)"); } catch (IOException ioex) { throw new ClassNotFoundException("IOException was thrown when trying to get all resources for " + pckgname); } ArrayList<Class> classes = new ArrayList<Class>(); // For every directoryFile identified capture all the .class files while (!directories.isEmpty()){ File directoryFile = directories.remove(0); if (directoryFile.exists()) { // Get the list of the files contained in the package File[] files = directoryFile.listFiles(); for (File file : files) { // we are only interested in .class files if ((file.getName().endsWith(".class")) && (!file.getName().contains("$"))) { // removes the .class extension int index = directoryFile.getPath().indexOf(packageToPath); String packagePrefix = directoryFile.getPath().substring(index).replace('/', '.');; try { String className = packagePrefix + '.' + file.getName().substring(0, file.getName().length() - 6); classes.add(Class.forName(className)); } catch (NoClassDefFoundError e) { // do nothing. this class hasn't been found by the loader, and we don't care. } } else if (file.isDirectory()){ // If we got to a subdirectory directories.add(new File(file.getPath())); } } } else { throw new ClassNotFoundException(pckgname + " (" + directoryFile.getPath() + ") does not appear to be a valid package"); } } return classes; } 

我把一个简单的github项目放在一起解决了这个问题:

https://github.com/ddopson/java-class-enumerator

它应该适用于基于文件的类path和jar文件。

如果在签出项目后运行“make”,它会打印出来:

  Cleaning... rm -rf build/ Building... javac -d build/classes src/pro/ddopson/ClassEnumerator.java src/test/ClassIShouldFindOne.java src/test/ClassIShouldFindTwo.java src/test/subpkg/ClassIShouldFindThree.java src/test/TestClassEnumeration.java Making JAR Files... jar cf build/ClassEnumerator_test.jar -C build/classes/ . jar cf build/ClassEnumerator.jar -C build/classes/ pro Running Filesystem Classpath Test... java -classpath build/classes test.TestClassEnumeration ClassDiscovery: Package: 'test' becomes Resource: 'file:/Users/Dopson/work/other/java-class-enumeration/build/classes/test' ClassDiscovery: Reading Directory '/Users/Dopson/work/other/java-class-enumeration/build/classes/test' ClassDiscovery: FileName 'ClassIShouldFindOne.class' => class 'test.ClassIShouldFindOne' ClassDiscovery: FileName 'ClassIShouldFindTwo.class' => class 'test.ClassIShouldFindTwo' ClassDiscovery: FileName 'subpkg' => class 'null' ClassDiscovery: Reading Directory '/Users/Dopson/work/other/java-class-enumeration/build/classes/test/subpkg' ClassDiscovery: FileName 'ClassIShouldFindThree.class' => class 'test.subpkg.ClassIShouldFindThree' ClassDiscovery: FileName 'TestClassEnumeration.class' => class 'test.TestClassEnumeration' Running JAR Classpath Test... java -classpath build/ClassEnumerator_test.jar test.TestClassEnumeration ClassDiscovery: Package: 'test' becomes Resource: 'jar:file:/Users/Dopson/work/other/java-class-enumeration/build/ClassEnumerator_test.jar!/test' ClassDiscovery: Reading JAR file: '/Users/Dopson/work/other/java-class-enumeration/build/ClassEnumerator_test.jar' ClassDiscovery: JarEntry 'META-INF/' => class 'null' ClassDiscovery: JarEntry 'META-INF/MANIFEST.MF' => class 'null' ClassDiscovery: JarEntry 'pro/' => class 'null' ClassDiscovery: JarEntry 'pro/ddopson/' => class 'null' ClassDiscovery: JarEntry 'pro/ddopson/ClassEnumerator.class' => class 'null' ClassDiscovery: JarEntry 'test/' => class 'null' ClassDiscovery: JarEntry 'test/ClassIShouldFindOne.class' => class 'test.ClassIShouldFindOne' ClassDiscovery: JarEntry 'test/ClassIShouldFindTwo.class' => class 'test.ClassIShouldFindTwo' ClassDiscovery: JarEntry 'test/subpkg/' => class 'null' ClassDiscovery: JarEntry 'test/subpkg/ClassIShouldFindThree.class' => class 'test.subpkg.ClassIShouldFindThree' ClassDiscovery: JarEntry 'test/TestClassEnumeration.class' => class 'test.TestClassEnumeration' Tests Passed. 

另见我的其他答案

您需要在类path中查找每个类加载器条目:

  String pkg = "org/apache/commons/lang"; ClassLoader cl = ClassLoader.getSystemClassLoader(); URL[] urls = ((URLClassLoader) cl).getURLs(); for (URL url : urls) { System.out.println(url.getFile()); File jar = new File(url.getFile()); // .... } 

如果entry是目录,只需在右边的子目录中查找:

 if (jar.isDirectory()) { File subdir = new File(jar, pkg); if (!subdir.exists()) continue; File[] files = subdir.listFiles(); for (File file : files) { if (!file.isFile()) continue; if (file.getName().endsWith(".class")) System.out.println("Found class: " + file.getName().substring(0, file.getName().length() - 6)); } } 

如果条目是文件,并且是jar,请检查它的ZIP条目:

 else { // try to open as ZIP try { ZipFile zip = new ZipFile(jar); for (Enumeration<? extends ZipEntry> entries = zip .entries(); entries.hasMoreElements();) { ZipEntry entry = entries.nextElement(); String name = entry.getName(); if (!name.startsWith(pkg)) continue; name = name.substring(pkg.length() + 1); if (name.indexOf('/') < 0 && name.endsWith(".class")) System.out.println("Found class: " + name.substring(0, name.length() - 6)); } } catch (ZipException e) { System.out.println("Not a ZIP: " + e.getMessage()); } catch (IOException e) { System.err.println(e.getMessage()); } } 

现在一旦你有了包的所有类名,你可以尝试使用reflection来加载它们,并分析它们是类还是接口等等。

我一直在尝试使用reflection库,但有一些使用它的问题,并有太多的瓶子,我应该包括只是为了简单地获得一个包上的类。

我将发布一个我在这个重复的问题中find的解决scheme: 如何获取包中的所有类名称?

答案是由sp00m写的 ; 我已经添加了一些更正,使其工作:

 import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; public final class ClassFinder { private final static char DOT = '.'; private final static char SLASH = '/'; private final static String CLASS_SUFFIX = ".class"; private final static String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the given '%s' package exists?"; public final static List<Class<?>> find(final String scannedPackage) { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final String scannedPath = scannedPackage.replace(DOT, SLASH); final Enumeration<URL> resources; try { resources = classLoader.getResources(scannedPath); } catch (IOException e) { throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage), e); } final List<Class<?>> classes = new LinkedList<Class<?>>(); while (resources.hasMoreElements()) { final File file = new File(resources.nextElement().getFile()); classes.addAll(find(file, scannedPackage)); } return classes; } private final static List<Class<?>> find(final File file, final String scannedPackage) { final List<Class<?>> classes = new LinkedList<Class<?>>(); if (file.isDirectory()) { for (File nestedFile : file.listFiles()) { classes.addAll(find(nestedFile, scannedPackage)); } //File names with the $1, $2 holds the anonymous inner classes, we are not interested on them. } else if (file.getName().endsWith(CLASS_SUFFIX) && !file.getName().contains("$")) { final int beginIndex = 0; final int endIndex = file.getName().length() - CLASS_SUFFIX.length(); final String className = file.getName().substring(beginIndex, endIndex); try { final String resource = scannedPackage + DOT + className; classes.add(Class.forName(resource)); } catch (ClassNotFoundException ignore) { } } return classes; } } 

要使用它,只需调用本示例中提到的sp00n中的find方法:如果需要,我已经添加了类的实例的创build。

 List<Class<?>> classes = ClassFinder.find("com.package"); ExcelReporting excelReporting; for (Class<?> aClass : classes) { Constructor constructor = aClass.getConstructor(); //Create an object of the class type constructor.newInstance(); //... } 

I wrote FastClasspathScanner to solve this problem. It handles many different types of classpath scanning tasks, has a simple API, works with many different ClassLoaders and classpath environments, has been carefully parallelized and is highly optimized for high speed and low memory consumption. It can even generate a GraphViz visualization of the class graph, showing how classes are connected to each other.

For your original question of finding all classes or interfaces in a given package, you can do:

 List<String> classNames = new FastClasspathScanner("com.mypackage").scan() .getNamesOfAllClasses(); 

There are many possible variants to this — see the documentation (linked above) for full info.

Yeah using few API's you can, here is how i like doing it, faced this problem which i was using hibernate core & had to find classes which where annotated with a certain annotation.

Make these an custom annotation using which you will mark which classes you want to be picked up.

 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface EntityToBeScanned { } 

Then mark your class with it like

 @EntityToBeScanned public MyClass{ } 

Make this utility class which has the following method

 public class ClassScanner { public static Set<Class<?>> allFoundClassesAnnotatedWithEntityToBeScanned(){ Reflections reflections = new Reflections(".*"); Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(EntityToBeScanned.class); return annotated; } } 

Call the allFoundClassesAnnotatedWithEntityToBeScanned() method to get a Set of Classes found.

You will need libs given below

 <!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>21.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.javassist/javassist --> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.22.0-CR1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.reflections/reflections --> <dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.10</version> </dependency> 

Almost all the answers either uses Reflections or reads class files from file system. If you try to read classes from file system, you may get errors when you package your application as JAR or other. Also you may not want to use a separate library for that purpose.

Here is another approach which is pure java and not depends on file system.

 import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class PackageUtil { public static Collection<Class> getClasses(final String pack) throws Exception { final StandardJavaFileManager fileManager = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); return StreamSupport.stream(fileManager.list(StandardLocation.CLASS_PATH, pack, Collections.singleton(JavaFileObject.Kind.CLASS), false).spliterator(), false) .map(javaFileObject -> { try { final String[] split = javaFileObject.getName() .replace(".class", "") .replace(")", "") .split(Pattern.quote(File.separator)); final String fullClassName = pack + "." + split[split.length - 1]; return Class.forName(fullClassName); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } }) .collect(Collectors.toCollection(ArrayList::new)); } } 

Java 8 is not a must . You can use for loops instead of streams. And you can test it like this

 public static void main(String[] args) throws Exception { final String pack = "java.nio.file"; // Or any other package PackageUtil.getClasses(pack).stream().forEach(System.out::println); } 

Worth mentioning

If you want to have a list of all classes under some package, you can use Reflection the following way:

 List<Class> myTypes = new ArrayList<>(); Reflections reflections = new Reflections("com.package"); for (String s : reflections.getStore().get(SubTypesScanner.class).values()) { myTypes.add(Class.forName(s)); } 

This will create a list of classes that later you can use them as you wish.

Provided you are not using any dynamic class loaders you can search the classpath and for each entry search the directory or JAR file.

I just wrote a util class, it include test methods, you can have a check ~

IteratePackageUtil.java:

 package eric.j2se.reflect; import java.util.Set; import org.reflections.Reflections; import org.reflections.scanners.ResourcesScanner; import org.reflections.scanners.SubTypesScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import org.reflections.util.FilterBuilder; /** * an util to iterate class in a package, * * @author eric * @date Dec 10, 2013 12:36:46 AM */ public class IteratePackageUtil { /** * <p> * Get set of all class in a specified package recursively. this only support lib * </p> * <p> * class of sub package will be included, inner class will be included, * </p> * <p> * could load class that use the same classloader of current class, can't load system packages, * </p> * * @param pkg * path of a package * @return */ public static Set<Class<? extends Object>> getClazzSet(String pkg) { // prepare reflection, include direct subclass of Object.class Reflections reflections = new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner(false), new ResourcesScanner()) .setUrls(ClasspathHelper.forClassLoader(ClasspathHelper.classLoaders(new ClassLoader[0]))) .filterInputsBy(new FilterBuilder().includePackage(pkg))); return reflections.getSubTypesOf(Object.class); } public static void test() { String pkg = "org.apache.tomcat.util"; Set<Class<? extends Object>> clazzSet = getClazzSet(pkg); for (Class<? extends Object> clazz : clazzSet) { System.out.println(clazz.getName()); } } public static void main(String[] args) { test(); } } 

It is very possible, but without additional libraries like Reflections it is hard…
It is hard because you haven't full instrument for get class name.
And, I take the code of my ClassFinder class:

 package play.util; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * Created by LINKOR on 26.05.2017 in 15:12. * Date: 2017.05.26 */ public class FileClassFinder { private JarFile file; private boolean trouble; public FileClassFinder(String filePath) { try { file = new JarFile(filePath); } catch (IOException e) { trouble = true; } } public List<String> findClasses(String pkg) { ArrayList<String> classes = new ArrayList<>(); Enumeration<JarEntry> entries = file.entries(); while (entries.hasMoreElements()) { JarEntry cls = entries.nextElement(); if (!cls.isDirectory()) { String fileName = cls.getName(); String className = fileName.replaceAll("/", ".").replaceAll(File.pathSeparator, ".").substring(0, fileName.lastIndexOf('.')); if (className.startsWith(pkg)) classes.add(className.substring(pkg.length() + 1)); } } return classes; } } 

Aleksander Blomskøld's solution did not work for me for parameterized tests @RunWith(Parameterized.class) when using Maven. The tests were named correctly and also where found but not executed:

 ------------------------------------------------------- TESTS ------------------------------------------------------- Running some.properly.named.test.run.with.maven.SomeTest Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.123 sec 

A similar issue has been reported here .

In my case @Parameters is creating instances of each class in a package. The tests worked well when run locally in the IDE. However, when running Maven no classes where found with Aleksander Blomskøld's solution.

I did make it work with the following snipped which was inspired by David Pärsson's comment on Aleksander Blomskøld's answer:

 Reflections reflections = new Reflections(new ConfigurationBuilder() .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) .addUrls(ClasspathHelper.forJavaClassPath()) .filterInputsBy(new FilterBuilder() .include(FilterBuilder.prefix(basePackage)))); Set<Class<?>> subTypesOf = reflections.getSubTypesOf(Object.class); 

Based on @Staale's answer , and in an attempt not to rely on third party libraries, I would implement the File System approach by inspecting first package physical location with:

 import java.io.File; import java.io.FileFilter; import java.util.ArrayList; ... Class<?>[] foundClasses = new Class<?>[0]; final ArrayList<Class<?>> foundClassesDyn = new ArrayList<Class<?>>(); new java.io.File( klass.getResource( "/" + curPackage.replace( "." , "/") ).getFile() ).listFiles( new java.io.FileFilter() { public boolean accept(java.io.File file) { final String classExtension = ".class"; if ( file.isFile() && file.getName().endsWith(classExtension) // avoid inner classes && ! file.getName().contains("$") ) { try { String className = file.getName(); className = className.substring(0, className.length() - classExtension.length()); foundClassesDyn.add( Class.forName( curPackage + "." + className ) ); } catch (ClassNotFoundException e) { e.printStackTrace(System.out); } } return false; } } ); foundClasses = foundClassesDyn.toArray(foundClasses); 

If you are merely looking to load a group of related classes, then Spring can help you.

Spring can instantiate a list or map of all classes that implement a given interface in one line of code. The list or map will contain instances of all the classes that implement that interface.

That being said, as an alternative to loading the list of classes out of the file system, instead just implement the same interface in all the classes you want to load, regardless of package and use Spring to provide you instances of all of them. That way, you can load (and instantiate) all the classes you desire regardless of what package they are in.

On the other hand, if having them all in a package is what you want, then simply have all the classes in that package implement a given interface.

It is not possible, since all classes in the package might not be loaded, while you always knows package of a class.