Why does Java disallow inheritance from a class whose constructor is private?
-
2@HovercraftFullOfEels, see Peter Lawrey's answer. – CodeBlue May 21 '13 at 07:00
6 Answers
Java doesn't prevent sub-classing of class with private constructors.
public class Main {
static class A {
private A() {
System.out.println("Subclassed A in "+getClass().getName());
}
}
static class B extends A {
public B() {
}
}
public static void main(String... ignored) {
new B();
}
}
prints
Subclassed A in Main$B
What it prevents is sub-classes which cannot access any constructors of its super class. This means a private constructor cannot be used in another class file, and a package local constructor cannot be used in another package.
In this situation, the only option you have is delegation. You need to call a factory method to create an instance of the "super" class and wrap it.

- 89,107
- 13
- 149
- 217

- 525,659
- 79
- 751
- 1,130
-
something is not right? instantiate a nested static class? how does it work? – Jaxox Oct 15 '14 at 05:36
-
@jaxox to the jvm, nested classes are nothing special. They are like any other class with a but more meta information. So you can create a class which was defined an nested in same way as any other. Btw anonymous classes in static methods are also static nested classes. – Peter Lawrey Oct 16 '14 at 06:49
-
@PeterLawrey I kind of get what you are saying, but I am still slightly confused. Didn't you say that Java doesn't allow subclasses being unable to access respective superclass constructors. Well in your example, class B doesn't have access to A's constructor. So how is that allowed ? – Grateful May 26 '15 at 02:56
-
@Grateful B can access the members of A as they are in the same outer class. This is true for fields and methods also. However if A and B were not in the same file and A had private or even package local constructors and B couldn't access them, in this case B cannot subclass A. – Peter Lawrey May 26 '15 at 04:14
-
@PeterLawrey That's fine. I am interested in knowing more about how class B is going around the problem of A() being private. Just because both classes are nested within the same outer class... does it really qualify one class to access the private constructor of the other ? Or is it calling the default constructor of the outer class and completely ignoring the class A constructor ? – Grateful May 26 '15 at 05:36
-
@Grateful actually the fact the code is in the same outer class does all it to access private members. The JVM doesn't allow this so the compiler creates accessor methods like `access $010` – Peter Lawrey May 26 '15 at 06:43
-
@PeterLawrey Sorry, I didn't understand the last comment. Would you have time to elaborate ? – Grateful May 26 '15 at 08:13
-
@Grateful While Java allows access to private members of other classes, the JVM doesn't. What the compiler does is create accessor methods which to allow the Java code to access fields/methods/constructors you wouldn't otherwise be able to access. – Peter Lawrey May 26 '15 at 21:36
-
3@PeterLawrey Okay, I guess the simple explanation for me is that Java allows private constructors of fellow nested classes to be accessed. – Grateful May 27 '15 at 00:43
-
@Grateful note, this applies to fields, methods and even private nest classes too. – Peter Lawrey May 27 '15 at 04:37
-
Point of further pedantry: You can, in byte code, create a class without a constructor. You can even create an instance if the base class is serialisable. / Perhaps worth pointing out that you can never override a private method, because of JDK 1.00. – Tom Hawtin - tackline Jan 08 '19 at 20:16
-
@TomHawtin-tackline `Unsafe.allocateInstance(Class)` creates an instance of a class without calling a constructor. It can create new Enum values, but not instances of `Class` ;) – Peter Lawrey Jan 08 '19 at 21:46
-
1@PeterLawrey Well, yeah if you take the safety catches off... What's interesting, IMO, is what you can do without having first damaged the integrity of the environment. – Tom Hawtin - tackline Jan 08 '19 at 22:45
-
@TomHawtin-tackline you can use Unsafe to copy the Class pointer in the header from one object to another to "cast" one type to another. ;) – Peter Lawrey Jan 08 '19 at 22:52
Because a class must call its super class constructor always. If the super class constructor can't be accessed, then the sub class can't be initialized.
More info: JLS 8.8.10. Preventing Instantiation of a Class
Regarding Brian Roach's comments:
The call [to the parent class constructor] is only implicit if you don't do it explicitly and the parent has a public or protected no-arg constructor (or hasn't defined any in which case there's a default no-arg). It's required because ... that's how the language works. Children [classes] must call [their] parent's constructor.
Note that when you instantiate any class in Java, there's always a implicit call to Object
constructor since it is the super class of all classes. It will execute its default constructor:
public Object() {
}
Note from the JLS link:
It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor (§6.6) that takes no arguments and has no throws clause.

- 85,076
- 16
- 154
- 332
-
-
2If the parent class has declared a private constructor then there's nothing implicit about it. It would require an explicit call in the child, but because the constructor is private, you can't. – Brian Roach May 21 '13 at 03:28
-
There is an implicit call to super() in every constructor unless you specify one yourself. – cogsmos May 21 '13 at 03:29
-
I am referring to the call to super being implicit. Why is it necessary to call super in the first place? Is it just the way they designed it or is there a good reason for that? – CodeBlue May 21 '13 at 03:32
-
1THe call is only implicit if you don't do it explicitly and the parent has a public or protected no-arg constructor (or hasn't defined any in which case there's a default public no-arg). It's required because ... that's how the language works. Children must call the parent's constructor. – Brian Roach May 21 '13 at 03:34
If constructor of a class is private then child class cannot make call to super constructor. Hence inheritance would fail.

- 7,810
- 6
- 48
- 78
If you have a subclass, you have 2 possiblities for child class(subclass) constructors : 1. Default Constructor(No argument constructor) : In this case default constructor will automatically try to call the parent class constructor : this will fail since parent class constructor is private. 2. Parameterized Constructor : When you try to create an object for a child class which has parameterized constructor, you need to mandatorily call parent class constructor from child class constructor by either passing parameters or not passing parameters : this will also fail since parent constructor is private.
Since child class will have either default constructor or parameterized constructor and its not possible to have either of them, you cannot have a subclass for a parent class with private constructor.

- 11
- 1
Yes adding something to Luiggi's answer this feature of java is used when creating the Singleton classes which allows only one instance of that class to be created.

- 4,706
- 9
- 36
- 50
-
@Brian can you please tell me how to do it correctly without making the constructor private? – Sanjaya Liyanage May 21 '13 at 03:32
-
2Josh Bloch, 'Effective Java second edition' - use an `enum`. See: http://stackoverflow.com/questions/5759596/the-best-singleton-pattern-since-java-5 . If you don't have that book, buy it. It's a must-read for anyone serious about java – Brian Roach May 21 '13 at 03:36
This is because, When we do inheritance the job of the compiler is to make a direct or indirect relation of all the classes with the Object class by writing the super() at the very first statement of every class constructor . when we make the constructor as private that means it shouldn't be accessed from outside the class but when we do inheritance compiler will implicitly write this type of statement.
class SubClassName extends SuperClassName {
public SubClassName() {
super(); // which will indirectly going to call the Parent class constructor from outside its scope
}
}

- 2,544
- 3
- 25
- 31

- 75
- 6