Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class.getClasses() not working with inherited classes from interface

Can someone explain why test() passes while testInheritance() not ?

public class IPanDeviceEnclosedClassesTest {

    public static interface Root {
       class Enclosed {}
    }

    public static interface Leaf extends Root {}

    @Test
    public void testInheritance() {
        Class<?> enclosing  = Leaf.class;
        Class<?>[] enclosed = enclosing.getClasses();
        assertNotEquals(0, enclosed.length);
    }

    @Test
    public void test() {
        Class<?> enclosing  = Root.class;
        Class<?>[] enclosed = enclosing.getClasses(); // getDeclaredClasses() works as well
        assertNotEquals(0, enclosed.length);
    }
}
like image 606
Antoine Marques Avatar asked Feb 14 '26 15:02

Antoine Marques


1 Answers

The answer lies in the highlighted bit from the getClasses javadoc

Returns an array containing Class objects representing all the public classes and interfaces that are members of the class represented by this Class object. This includes public class and interface members inherited from superclasses and public class and interface members declared by the class.

From what I can tell, getClasses() returns classes that it inherits from a superclass as well as the static classes of its superclass. An interface is not a superclass, so as per the javadoc we shouldn't expect that any static classes declared on the interface will be returned.

Out the following inheritance tests, only testInheritanceClasses passes.

1) Class extending a superclass sees Enclosed:

public static class RootClass {
      public static class Enclosed {}
}

public static class LeafClass extends RootClass {}

@Test
public void testInheritanceClasses() {
    Class<?> enclosing  = LeafClass.class;
    Class<?>[] enclosed = enclosing.getClasses();
    System.out.println(Arrays.deepToString(enclosed));
    Assert.assertNotEquals(0, enclosed.length);
}

2) Interface "extending" an interface does not see Enclosed

public interface Root {
    class Enclosed {}
}

public interface Leaf extends Root {}

@Test
public void testInheritanceInterfaces() {
     Class<?> enclosing  = Leaf.class;
     Class<?>[] enclosed = enclosing.getClasses();
     System.out.println(Arrays.deepToString(enclosed));
     Assert.assertNotEquals(0, enclosed.length);
}

3) Class implementing an interface does not see Enclosed:

public interface Root {
    class Enclosed {}
} 

public static class LeafImplementingRoot implements Root {}        


@Test
public void testInheritanceImplements() {
    Class<?> enclosing  = LeafImplementingRoot.class;
    Class<?>[] enclosed = enclosing.getClasses();
    System.out.println(Arrays.deepToString(enclosed));
    Assert.assertNotEquals(0, enclosed.length);
}
like image 88
cyon Avatar answered Feb 17 '26 03:02

cyon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!