How to Find All Subclasses of a Given Class in Java

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

There is no other way to do it other than what you described. Think about it - how can anyone know what classes extend ClassX without scanning each class on the classpath?

Eclipse can only tell you about the super and subclasses in what seems to be an "efficient" amount of time because it already has all of the type data loaded at the point where you press the "Display in Type Hierarchy" button (since it is constantly compiling your classes, knows about everything on the classpath, etc).

Is it possible to get all the subclasses of a class?

The short answer is no.

The long answer is that subclasses can come into existence in many ways, which basically makes it impossible to categorically find them all.

You can't do it at runtime but you can't find classes until they're loaded and how do you know they're loaded? You could scan every JAR and class file but that's not definitive. Plus there are things like URL class loaders.

Inner classes (static and non-static) are another case to consider. Named inner classes are easier to find. Anonymous inner classes are potentially much more difficult to find.

You also have to consider that if a class has subclasses then new subclasses can be created at a later point.

How to find which subclasses of given class implement a particular interface in Eclipse?

You can use the java search in two steps:

Assuming subclasses C1 and C3 of A implement B, but C2 does not:

In the first step, select class A and search for all subclasses of A using the java search (Search->Java...) with option implementors:

Sample Image

Then the search view pops up and we see all subclasses of A:

Sample Image

Select them and hit "Search->Java..." again. Now we can search within this selection for implementors of B.

Sample Image

This gives us subclasses of A that implement B:

Sample Image

find subclasses of a given class in jdk lib

Why do you not try one of the solutions from your link?

Find below a simple example using https://github.com/ronmamo/reflections.git.

After having a look in the test classes this example was straight forward.

Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(Arrays.asList(ClasspathHelper.forClass(List.class))));

Set<Class<? extends List>> subTypes = reflections.getSubTypesOf(List.class);
for (Class c : subTypes) {
System.out.println("subType: " + c.getCanonicalName());
}

How to find all the subclasses of a class given its name?

New-style classes (i.e. subclassed from object, which is the default in Python 3) have a __subclasses__ method which returns the subclasses:

class Foo(object): pass
class Bar(Foo): pass
class Baz(Foo): pass
class Bing(Bar): pass

Here are the names of the subclasses:

print([cls.__name__ for cls in Foo.__subclasses__()])
# ['Bar', 'Baz']

Here are the subclasses themselves:

print(Foo.__subclasses__())
# [<class '__main__.Bar'>, <class '__main__.Baz'>]

Confirmation that the subclasses do indeed list Foo as their base:

for cls in Foo.__subclasses__():
print(cls.__base__)
# <class '__main__.Foo'>
# <class '__main__.Foo'>

Note if you want subsubclasses, you'll have to recurse:

def all_subclasses(cls):
return set(cls.__subclasses__()).union(
[s for c in cls.__subclasses__() for s in all_subclasses(c)])

print(all_subclasses(Foo))
# {<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>}

Note that if the class definition of a subclass hasn't been executed yet - for example, if the subclass's module hasn't been imported yet - then that subclass doesn't exist yet, and __subclasses__ won't find it.


You mentioned "given its name". Since Python classes are first-class objects, you don't need to use a string with the class's name in place of the class or anything like that. You can just use the class directly, and you probably should.

If you do have a string representing the name of a class and you want to find that class's subclasses, then there are two steps: find the class given its name, and then find the subclasses with __subclasses__ as above.

How to find the class from the name depends on where you're expecting to find it. If you're expecting to find it in the same module as the code that's trying to locate the class, then

cls = globals()[name]

would do the job, or in the unlikely case that you're expecting to find it in locals,

cls = locals()[name]

If the class could be in any module, then your name string should contain the fully-qualified name - something like 'pkg.module.Foo' instead of just 'Foo'. Use importlib to load the class's module, then retrieve the corresponding attribute:

import importlib
modname, _, clsname = name.rpartition('.')
mod = importlib.import_module(modname)
cls = getattr(mod, clsname)

However you find the class, cls.__subclasses__() would then return a list of its subclasses.



Related Topics



Leave a reply



Submit