Explain Codes LogoExplain Codes Logo

How do you find all subclasses of a given class in Java?

java
reflection
performance-optimization
subclass-discovery
Nikita BarsukovbyNikita Barsukov·Feb 14, 2025
TLDR

For a quick method of finding subclasses in Java, use the Reflections library. Add the library to your project and use this simple code snippet:

// You would need more than divine intervention to not make this code work Reflections reflections = new Reflections("my.package"); Set<Class<? extends BaseClass>> subclasses = reflections.getSubTypesOf(BaseClass.class);

Make sure to substitute my.package and BaseClass with your actual package and class, respectively. This code will retrieve all subclasses of BaseClass that are accessible from the given package.

While Reflections provides an efficient solution, other methods might be better suited for specific scenarios, especially concerning performance optimization in larger projects.

Extending your subclass discovery techniques

Utilizing Spring's subclass discovery

Within a Spring application, you can take advantage of built-in Spring framework classes to identify subclasses of a specific class:

// Spring is in the air...and the code ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); provider.addIncludeFilter(new AssignableTypeFilter(BaseClass.class)); // The side effect of too much Spring cleaning for (BeanDefinition beanDef : provider.findCandidateComponents("my.package")) { System.out.println(beanDef.getBeanClassName()); }

This method optimizes memory consumption and improves performance, making it strategically advantageous for larger applications.

Eclipse's type hierarchy for quick reference

In the Eclipse IDE, you can use the type hierarchy feature to avoid runtime overhead:

  1. Open your base class in the editor.
  2. Press Ctrl + T (Windows/Linux) or ⌘ + T (macOS) to reveal the type hierarchy.
  3. Browse through the list of subclasses.

While this method offers a swift visual reference, it is bound to your IDE and is not programmatically usable.

Scanning with ClassGraph: The universal solution

For a universal, efficient solution, consider using ClassGraph. It's versatile, working in multiple environments, including the Java Platform Module System (JPMS):

// Beware: ClassGraph does not graph classes try (ScanResult scanResult = new ClassGraph().enableClassInfo().whitelistPackages("com.my.package").scan()) { ClassInfoList subclasses = scanResult.getSubclasses("com.my.package.BaseClass"); subclasses.forEach(classInfo -> System.out.println(classInfo.getName())); }

ClassGraph is recognized for its agility in scanning runtime classpath, modules, and even JAR resources.

Javadoc: The good old documentation lookup

For a quick reference, use Javadoc. It lists all known subclasses in the documentation of the base class. While static, it offers an immediate, convenient way of finding subclasses.

Optimizing subclass discovery

Reflection versus performance

While Reflection-based techniques such as Reflections and ClassGraph offer dynamic resolution, performance impacts vary. It's critical to benchmark these techniques in the context of your application to ensure they're performance-optimized.

Classpath monitoring

In systems that require real-time awareness of classpath changes, consider implementing a file change monitor. This can be achieved using file system watchers or operating system-level notifications.

Tool selection: Choose wisely

Different tools offer varied performance benefits. When selecting a tool, consider class-loading behavior, memory consumption, and execution speed to align with project requirements.