有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何轻松迭代所有超级类/接口

迭代给定Class<?>对象的所有超类/接口的最优雅方式是什么?我基本上是在寻找一个递归的^{}^{}方法,收集整个类层次结构

让我们假设我们的继承如下所示(其中Cn是类In是接口):

         I3
        ↗  ↖
C2    I1    I2
  ↖     ↖  ↗
   C1    I0
     ↖  ↗ 
      C0

它应该捕获上面显示的所有类。如果可能的话,迭代顺序应该是breadth first,所以如下所示:

C0 -> C1 -> I0 -> C2 -> I1 -> I2 -> I3

是否有内置方法或库提供创建Collection<Class<?>>Stream<Class<?>>Iterator<Class<?>>的功能

欢迎任何帮助


共 (2) 个答案

  1. # 1 楼答案

    这个解决方案实现了一个Iterator<Class<?>>。如果你不介意使用库,我建议你签出the accepted answer

    public static class HierarchyIterator implements Iterator<Class<?>> {
        private Queue<Class<?>> remaining = new LinkedList<>();
        private Set<Class<?>> visited = new LinkedHashSet<>();
    
        public HierarchyIterator(Class<?> initial) {
            append(initial);
        }
    
        private void append(Class<?> toAppend) {
            if (toAppend != null && !visited.contains(toAppend)) {
                remaining.add(toAppend);
                visited.add(toAppend);
            }
        }
    
        @Override
        public boolean hasNext() {
            return remaining.size() > 0;
        }
    
        @Override
        public Class<?> next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            Class<?> polled = remaining.poll();
            append(polled.getSuperclass());
            for (Class<?> superInterface : polled.getInterfaces()) {
                append(superInterface);
            }
            return polled;
        }
    }
    

    如果需要Collection<Class<?>>,可以使用Google Guava进行以下操作:

    public static Set<Class<?>> getClassHierarchy(Class<?> forClass) {
        Set<Class<?>> result = new LinkedHashSet<>();
        Iterators.addAll(result, new HierarchyIterator(forClass));
        return result;
    }
    

    电话:

    System.out.println(getClassHierarchy(LinkedList.class));
    

    屈服

    [class java.util.LinkedList, class java.util.AbstractSequentialList, interface java.util.List, interface java.util.Deque, interface java.lang.Cloneable, interface java.io.Serializable, class java.util.AbstractList, interface java.util.Collection, interface java.util.Queue, class java.util.AbstractCollection, interface java.lang.Iterable, class java.lang.Object] 
    
  2. # 2 楼答案

    下面是一个快速的广度优先层次结构:

    public class ClassHierarchy {
        private Queue<Class<?>> queue;
        //a collection of "visited" classes,
        //which is also the result of the search
        private Set<Class<?>> visited;
    
        public Set<Class<?>> getClassHierarchy(Class<?> cls){
            visited = new LinkedHashSet<>(); //initialize visited log
            bfs(cls);
            return visited;
        }
    
        //breadth first traverse on hierarchy
        private void bfs(Class<?> cls) {
    
            if(cls == null){ return; }
            queue = new LinkedList<>(); //initialize queue
            queue.add(cls);
            while (! queue.isEmpty()) {
               cls = queue.poll();
               //loop over super classes
               for(Class<?> nextClass : getSuperClasses(cls)){
                    if((nextClass != null) &&  visited.add(nextClass)) {
                         queue.add(nextClass); //add class to the queue
                    }
               }
            }
            return;
        }
    
        private List<Class<?>> getSuperClasses(Class<?> cls) {
             List<Class<?>> superCs = new ArrayList<>();
             superCs.addAll(Arrays.asList(cls.getInterfaces()));
             superCs.add(cls.getSuperclass());
             return superCs;
        }
    
        private boolean isVisited(Class<?> cls) {
            return !(visited.add(cls));
        }
    
        public static void main(String[] args) {
            ClassHierarchy ch = new ClassHierarchy();
            System.out.println(ch.getClassHierarchy(LinkedList.class));
        }
    }
    

    (请仔细检查。我还没有时间调试和改进。稍后再看)