Why is the default constructor of a Subclass not available through reflection?

Viewed 109

When running this:

import java.util.Arrays;

public class TestA {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(TestB.class.getConstructors()));
    }
}

class TestB extends TestA {

}

The result will be

[]

When calling the default constructor using reflection, the code will crash with NoMethodFoundException: TestB.<init>(). So somehow the JVM doesn't know that there is a default constructor. BUT when you simple call new TestB(), everything is fine (as it should be).

Adding to that, when I decompile the .class files, both classes have a default constructor.

What's going on under the hood or what am I missing?

1 Answers

getConstructors:

Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.

The constructor of TestB is not public! According to JLS §8.8.9:

If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:

  • The default constructor has the same accessibility as the class.
  • ...

TestB has the "package" access level (no access modifiers), so the default constructor has that access level too. Therefore, getConstructors doesn't include it in its returned array. It turns out this has nothing to do with TestB being a subclass of TestA.

If you want to get it, use getDeclaredConstructors.

Related