find all classes and interfaces a class extends or implements recursively

后端 未结 8 1217
孤独总比滥情好
孤独总比滥情好 2021-02-12 22:13

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:

cla         


        
相关标签:
8条回答
  • 2021-02-12 22:21

    If I got your question right, you want to find all the superclasses (class and interface) of a specific class. If so you can check the following solution

    to find the superclasses

            Class C = getClass();
            while (C != null) {
              System.out.println(C.getSimpleName());
              C = C.getSuperclass();
            }
    

    to find the interfaces

            C = getClass();
            for(Class adf: C.getInterfaces()){
    
                  System.out.println(adf.getSimpleName());
            }
    
    0 讨论(0)
  • 2021-02-12 22:23

    I have once implemented similiar mechanism using asm on some ShrinkWrap branch https://github.com/mmatloka/shrinkwrap/commit/39d5c3aa63a9bb85e6d7b68782879ca10cca273b . The issue is sometimes class might use object which is an interface implementation not mentioned in other file so it still can fail during deployment.

    From what I know some time ago official position was rather not to include such feature inside of the ShrinkWrap, but rather rely on tooling e.g. JBoss Tools, where should be a feature allowing for recursive class additions.

    0 讨论(0)
  • 2021-02-12 22:25

    There is a ClassUtils in the Apache Common Lang that have the 2 methods you want. .getAllSuperClasses() and .getAllInterfaces().

    0 讨论(0)
  • 2021-02-12 22:26

    It's very easy, in case your class is Foo then your code will be like this,

    public void getClassDetails() {
    
        Class klass = Foo.class;
        Class<?> superKlass = klass.getSuperClass();
        Class[] interfaces = klass.getInterfaces();
    }
    
    0 讨论(0)
  • 2021-02-12 22:34

    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
    
    0 讨论(0)
  • 2021-02-12 22:36

    The key you want is in the Class#getSuperclass() method:

    public static Set<Class<?>> stuff(Class<?> target) {
        Set<Class<?>> classesInterfaces = new HashSet<>();
        classesInterfaces.add(target);
        classesInterfaces.addAll(Arrays.asList(target.getInterfaces());
    
        Class<?> superClass = target.getSuperclass();
        if(superClass != null)
            classesInterfaces.addAll(stuff(superClass));
    }
    
    0 讨论(0)
提交回复
热议问题