Permalink
Browse files

Adds method to get inherited classes

This method recursively analyse a class to get all its super classes, and
all its interfaces
  • Loading branch information...
a-peyrard committed Feb 15, 2015
1 parent b2b99fd commit b54562c969681b5a0619da164e877b8fb48d6281
@@ -0,0 +1,43 @@
package restx.common;
import com.google.common.collect.Sets;
import java.util.Set;
/**
* Provides static utility methods to deal with {@link Class}
*
* @author apeyrard
*/
public class MoreClasses {
private MoreClasses() {}
/**
* Gets all inherited classes for a specified class (in a flat structure). Its super classes, and its interfaces.
*
* This process is recursive, if class A inherit from B which also inherit from C and D, the result will
* be (B, C, D).
*
* @param clazz the clazz to analyse
* @return the list of inherited classes
*/
public static Set<Class> getInheritedClasses(Class clazz) {
Set<Class> inheritedClasses = Sets.newHashSet();
// add super class, and add recursively their inherited classes
Class superClass = clazz.getSuperclass();
if (superClass != null) {
inheritedClasses.add(superClass);
inheritedClasses.addAll(getInheritedClasses(superClass));
}
// add all interfaces, and recursively add their inherited classes
Class[] interfaces = clazz.getInterfaces();
for (Class anInterface : interfaces) {
inheritedClasses.add(anInterface);
inheritedClasses.addAll(getInheritedClasses(anInterface));
}
return inheritedClasses;
}
}
@@ -0,0 +1,86 @@
package restx.common;
import static org.assertj.core.api.Assertions.assertThat;
import static restx.common.MoreClasses.getInheritedClasses;
import org.junit.Test;
import java.io.Closeable;
import java.io.Externalizable;
import java.io.FileOutputStream;
import java.io.Flushable;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.RandomAccess;
/**
* Test cases for {@link MoreClasses}
*
* @author apeyrard
*/
public class MoreClassesTest {
@Test
public void should_not_find_inherited_classes_for_primitive_types() {
assertThat(getInheritedClasses(void.class)).isEmpty();
assertThat(getInheritedClasses(int.class)).isEmpty();
assertThat(getInheritedClasses(double.class)).isEmpty();
}
public static class DummyClass { }
@Test
public void should_at_least_find_Object_class_for_classes_without_explicit_inheritance() {
assertThat(getInheritedClasses(DummyClass.class)).containsExactly(Object.class);
}
@Test
public void should_work_for_interfaces() {
assertThat(getInheritedClasses(Externalizable.class)).containsExactly(Serializable.class);
}
@Test
public void should_find_inherited_interfaces() {
assertThat(getInheritedClasses(Number.class)).containsOnly(Serializable.class, Object.class);
assertThat(getInheritedClasses(AbstractCollection.class)).containsOnly(Collection.class, Iterable.class, Object.class);
}
public static class A { }
public static class B extends A { }
public static class C extends B { }
@Test
public void should_find_inherited_super_classes() {
assertThat(getInheritedClasses(B.class)).containsOnly(A.class, Object.class);
assertThat(getInheritedClasses(C.class)).containsOnly(B.class, A.class, Object.class);
}
@Test
public void should_find_superclasses_and_interfaces() {
assertThat(getInheritedClasses(ArrayList.class)).containsOnly(
AbstractList.class,
AbstractCollection.class,
Object.class,
List.class,
Collection.class,
Iterable.class,
Serializable.class,
RandomAccess.class,
Cloneable.class
);
assertThat(getInheritedClasses(FileOutputStream.class)).containsOnly(
OutputStream.class,
Object.class,
Closeable.class,
AutoCloseable.class,
Flushable.class
);
}
}

0 comments on commit b54562c

Please sign in to comment.