ReflectionUtils { @Nonnull @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", justification = "False positive on try-with-resources as of JDK11") public static Collection<Class<?>> nestedClassesOf(Class<?>... classes) { ClassGraph classGraph = new ClassGraph() .enableClassInfo() .ignoreClassVisibility(); stream(classes).map(Class::getClassLoader).distinct().forEach(classGraph::addClassLoader); stream(classes).map(ReflectionUtils::toPackageName).distinct().forEach(classGraph::whitelistPackages); try (ScanResult scanResult = classGraph.scan()) { Set<String> classNames = stream(classes).map(Class::getName).collect(toSet()); return concat( stream(classes), scanResult.getAllClasses() .stream() .filter(classInfo -> classNames.contains(classInfo.getName())) .flatMap(classInfo -> classInfo.getInnerClasses().stream()) .map(ClassInfo::loadClass) ).collect(toList()); } } private  ReflectionUtils(); static T readStaticFieldOrNull(String classname, String fieldName); @Nonnull @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", justification = "False positive on try-with-resources as of JDK11") static Collection<Class<?>> nestedClassesOf(Class<?>... classes); @Nonnull @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", justification = "False positive on try-with-resources as of JDK11") static Resources resourcesOf(String... packages); static String toClassResourceId(String name); static Class<?> loadClass(ClassLoader classLoader, String name); static T newInstance(ClassLoader classLoader, String name);  }
@Test public void when_nestedClassesOf_then_returnsAllNestedClasses() throws ClassNotFoundException { Collection<Class<?>> classes = ReflectionUtils.nestedClassesOf(OuterClass.class); assertThat(classes, containsInAnyOrder( OuterClass.class, OuterClass.NestedClass.class, OuterClass.NestedClass.DeeplyNestedClass.class, Class.forName(OuterClass.class.getName() + "$1"), Class.forName(OuterClass.NestedClass.DeeplyNestedClass.class.getName() + "$1") )); }