find all classes and interfaces a class extends or implements recursively

class, java, jboss-arquillian

Solution

The following implementation of the method does what the OP requires, it traverses the inheritance hierarchy for every class and interface:

public static Set<Class<?>> getAllExtendedOrImplementedTypesRecursively(Class<?> clazz) {
    List<Class<?>> res = new ArrayList<>();

    do {
        res.add(clazz);

        // First, add all the interfaces implemented by this class
        Class<?>[] interfaces = clazz.getInterfaces();
        if (interfaces.length > 0) {
            res.addAll(Arrays.asList(interfaces));

            for (Class<?> interfaze : interfaces) {
                res.addAll(getAllExtendedOrImplementedTypesRecursively(interfaze));
            }
        }

        // Add the super class
        Class<?> superClass = clazz.getSuperclass();

        // Interfaces does not have java,lang.Object as superclass, they have null, so break the cycle and return
        if (superClass == null) {
            break;
        }

        // Now inspect the superclass 
        clazz = superClass;
    } while (!"java.lang.Object".equals(clazz.getCanonicalName()));

    return new HashSet<Class<?>>(res);
}    

I tested with `JFrame.class` and I got the following:

Set<Class<?>> classes = getAllExtendedOrImplementedTypesRecursively(JFrame.class);
for (Class<?> clazz : classes) {
    System.out.println(clazz.getName());
}

Output:

java.awt.Container
java.awt.Frame
javax.swing.JFrame
javax.swing.TransferHandler$HasGetTransferHandler
java.awt.Window
javax.accessibility.Accessible
javax.swing.RootPaneContainer
java.awt.Component
javax.swing.WindowConstants
java.io.Serializable
java.awt.MenuContainer
java.awt.image.ImageObserver

UPDATE: For the OP's test case it prints:

test.I5
test.Bar
test.I2
test.I1
test.Foo
test.I3
test.I4

Problem

I was wondering if there was an easy way of determining the complete list of Types that a Java class extends or implements recursively? for instance: ``` class Foo extends Bar implements I1, I2 {...} class Bar implements I3 {...} interface I1 extends I4, I5 {...} interface I2 {...} interface I3 {...} interface I4 {...} interface I5 {...} class ClassUtil { public static Set<Class<?>> getAllExtendedOrImplementedTypesRecursively(Class<?> clazz){ ??? } } import static org.junit.Assert.*; public class ClassUtilTest { @Test public void shouldEqualClasses(){ Set<Class<?>> types = ClassUtil.getAllExtendedOrImplementedTypesRecursively(Foo.class); Set<Class<?>> checklist = new HashSet<>(); checklist.add(Foo.class); checklist.add(Bar.class); checklist.add(I1.class); checklist.add(I2.class); checklist.add(I3.class); checklist.add(I4.class); checklist.add(I5.class); assertTrue(checklist.containsAll(types)); assertTrue(types.containsAll(checklist)); } } ``` Think Arquillian ShrinkWrap creation helper. UPDATE: due to the Class object not implementing Comparable> I also need to find a way of creating a Set (or similar class) without implementing the Comparable interface (for instance, solely relying on the hashcode of the class object). UPDATE: changed the test to use hashset. derp.

Original source

Related problems