Generally I try to use "real objects" instead of static methods where possible. IMO this allows for a cleaner structuring of code compared to static helper classes.

So the idea is to have an object/class which represents a class hierarchy and offers methods for everything you need to do with it. If you just want to iterate over the complete hierarchy, just do `for(Class<? super T> clazz : hierarchy) { ... }`; If you want to filter the hierarchy or do other things with it, invoke one of the methods it offers. Representing a type's hierarchy with a real object also allows for future improvements, e.g. the filter method could internally cache filtered hierarchies.

Why do you think the API is misleading? To me, class hierarchies are one concept of the "domain" we're dealing with, so representing them as an object seems very natural to me. So once you get hold of a `ClassHierarchy` object, the IDE offers all the methods you can invoke on it. Personally I find that much more intuitive and simpler than having to think about which static helper class offers the required functionality.