Search code examples
javasubclassprivate-constructor

Why am I able to inherit & call a private constructor in a subclass?


I read that it is not possible to create a subclass from a class whose constructor is private but weirdly I am able to do it, is there something more to this snippet?

Please someone provide an easy to understand & satisfactory explanation.

public class app {

    public static void main(String[] args) {
        app ref = new app();
        myInheritedClass myVal = ref.new myInheritedClass(10);
        myVal.show();

    }

    int myValue = 100;

    class myClass {
        int data;

        private myClass(int data) {
            this.data = data;
        }

    }

    class myInheritedClass extends myClass {
        public myInheritedClass(int data) {
            super(data);
        }

        public void show() {
            System.out.println(data);
        }

    }
}

I ran this snippet on https://www.compilejava.net/ and the output was 10.


Solution

  • Because your classes are both nested classes (in your case, specifically inner classes), which means they're both part of the containing class, and so have access to all private things in that containing class, including each other's private bits.

    If they weren't nested classes, you wouldn't be able to access the superclass's private constructor in the subclass.

    More about nested classes in the nested class tutorial on the Oracle Java site.

    This compiles, because A and B are inner classes, which are nested classes (live copy):

    class Example
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            System.out.println("Ran at " + new java.util.Date());
        }
    
        class A {
            private A() {
            }
        }
        class B extends A {
            private B() {
                super();
            }
        }
    }
    

    This compiles, because A and B are static nested classes (live copy):

    class Example
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            System.out.println("Ran at " + new java.util.Date());
        }
    
        static class A {
            private A() {
            }
        }
        static class B extends A {
            private B() {
                super();
            }
        }
    }
    

    This does not compile because A's constructor is private; B cannot access it (I don't really need Example in this case, but I've included it in the two above, so for context...) (live copy):

    class Example
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            System.out.println("Ran at " + new java.util.Date());
        }
    }
    class A {
        private A() {
        }
    }
    class B extends A {
        private B() {
            super();    // COMPILATION FAILS HERE
        }
    }