getClassHierarchy static method

List<Class> getClassHierarchy(
  1. Class type
)

Retrieves the complete class hierarchy for the specified type, including all superclasses, interfaces, and special type relationships.

This method performs a comprehensive traversal of the type system to build a complete hierarchy that includes:

  • The original class
  • All superclasses (excluding Object initially, added at the end)
  • All interfaces implemented by each class in the hierarchy
  • Component types for arrays
  • Special handling for enums (adds Enum base class)
  • Object class as the root (added last if not already present)

Parameters

  • type: The Class to analyze for hierarchy information

Returns

A List<Class> containing all classes in the hierarchy, ordered by traversal sequence. The list maintains insertion order and prevents duplicates.

Algorithm

  1. Initial Setup: Creates empty hierarchy list and visited set
  2. Breadth-First Traversal: Processes each class level by level
  3. Superclass Addition: Adds direct superclass (if not Object or enum)
  4. Interface Addition: Adds all interfaces implemented by current class
  5. Array Handling: For arrays, processes component type separately
  6. Enum Handling: Adds Enum base class for enum types
  7. Object Addition: Ensures Object is included as root class

Examples

Basic Class Hierarchy

class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal implements Comparable<Dog> {}

final hierarchy = ClassUtils.getClassHierarchy(Class.of<Dog>());
// Result: [Dog, Mammal, Animal, Comparable<Dog>, Object]

Array Type Hierarchy

final hierarchy = ClassUtils.getClassHierarchy(Class.of<List<String>>());
// Includes both List<String> and String component relationships

Enum Type Hierarchy

enum Color { red, green, blue }

final hierarchy = ClassUtils.getClassHierarchy(Class.of<Color>());
// Result: [Color, Enum, Object] plus any interfaces

Performance Considerations

  • Uses visited set to prevent infinite loops in complex hierarchies
  • Processes interfaces efficiently without redundant traversal
  • Handles deep inheritance chains without stack overflow

Implementation

static List<Class> getClassHierarchy(Class type) {
  final result = _classHierarchy[type];
  if(result != null) {
    return result;
  }

  final hierarchy = <Class>[];
  final visited = <Type>{};
  final toProcess = <Class>[];

  _addToClassHierarchyEnd(type, hierarchy, visited);
  toProcess.add(type);

  while (toProcess.isNotEmpty) {
    final candidate = toProcess.removeAt(0);

    // Always get superclass from the actual candidate
    final superclass = candidate.getSuperClass();
    if (superclass != null && superclass.getType() != Object && !superclass.isEnum()) {
      if (_addToClassHierarchyEnd(superclass, hierarchy, visited)) {
        toProcess.add(superclass);
      }
    }

    // Always get interfaces from the actual candidate
    final interfaces = candidate.getAllInterfaces();
    for (final interface in interfaces) {
      if (_addToClassHierarchyEnd(interface, hierarchy, visited)) {
        toProcess.add(interface);
      }
    }

    // For arrays, also explore the component type separately
    if (candidate.isArray()) {
      final component = candidate.componentType()!;
      if (_addToClassHierarchyEnd(component, hierarchy, visited)) {
        toProcess.add(component);
      }
    }
  }

  if (type.isEnum()) {
    _addToClassHierarchyEnd(Class.of<Enum>(), hierarchy, visited);
    final enumInterfaces = Class.of<Enum>().getAllInterfaces();
    for (final interface in enumInterfaces) {
      _addToClassHierarchyEnd(interface, hierarchy, visited);
    }
  }

  // Only add Object if not already present
  if (!visited.contains(Object)) {
    hierarchy.add(Class.of<Object>());
  }

  _classHierarchy[type] = hierarchy;

  return hierarchy;
}