In Java, we have 4 access modifiers that we can apply to a member variable and methods. But, how about Constructors? How these access modifiers can be used with constructors in Java? Let us see.
We can very well use access modifiers with constructors in Java. These access modifiers work just the way they work on a member variable or member function.
If you declare a constructor using public, you can use it anywhere you want while instantiating the class. If you declare a constructor as private, you cannot use that constructor anywhere but within the class. If you declare a constructor without any access modifier, which is also called as default access modifier, you cannot access constructor in other packages. With protected, your sub-class can access the protected constructor even though it is within another package.
Let us elaborate on this with examples.
Declaring Constructor as Public
Declaring a constructor as public makes it eligible for instantiation, anybody can instantiate the class using new keyword followed by the constructor signature.
package com.techstackjournal.shape;
public class Circle {
public Circle() {
System.out.println("Circle no-arg constructor...");
}
public static void main(String[] args) {
Circle circle = new Cicle();
}
}
Declaring Constructor as Private
If you declare a constructor as private no one can create an instance of your class, but only that class can instantiate within itself. If you have come across Singleton classes, you must have noticed it. We declare a Singleton class constructor as private to prevent others from instantiating it.
package com.techstackjournal.shape;
public class Circle {
private Circle() {
System.out.println("Cicle no-arg constructor...");
}
}
package com.techstackjournal.shape;
public class Main {
public static void main(String[] args) {
Circle circle = new Circle();
}
}
We’ll get a compile error “error: Circle() has private access in Circle” if we compile Main class. Since we declared Circle constructor as private, we cannot access that constructor outside of that class.
Declaring Constructor as Default
If you declare constructor without any access modifier, it is a default access modifier. When you declare a constructor with a default access modifier, you will not be able to instantiate that class using that constructor outside of its current package. Also, you will not be able to extend the class outside of its current package.
package com.techstackjournal.shape;
public class Circle {
Circle() {
System.out.println("Cicle no-arg constructor...");
}
}
package com.techstackjournal;
import com.techstackjournal.shape.Circle;
public class Main {
public static void main(String[] args) {
Circle circle = new Circle();
}
}
In the above example, Circle class is within “com.techstackjournal.shape” package. However, we are trying to use it in Main class which is within “com.techstackjournal” package. Since, the Circle’s constructor is declared as default, we’ll not be able to instantiate the class outside of its package using that constructor.
package com.techstackjournal;
import com.techstackjournal.shape.Circle;
public class FillCircle extends Circle {
}
Above code also gives you an error, because FillCircle is extending Circle without providing any constructor. In this case, FillCircle wants to leverage Circle’s constructor. Since, Circle’s constructor has default access modifier, FillCircle cannot access that constructor from a different package.
Here, FillCircle has to explicitly declare a constructor which is not having default access modifier in super class. Since, the example above doesn’t have another constructor without default access, it is not at all possible to extend Circle class in FillCircle.
For example, if Circle class has another overloaded constructor with public access modifier, FillCircle could use that constructor to avoid this problem.
Declaring Constructor as Protected
By declaring a constructor as protected, you can call that constructor in subclass when you instantiate the subclass, even when the subclass is located in a different package than the super class.
package com.techstackjournal.shape;
public class Circle {
protected Circle() {
System.out.println("Cicle no-arg constructor...");
}
}
package com.techstackjournal;
import com.techstackjournal.shape.Circle;
public class FillCircle extends Circle {
}
In the above example, FillCircle can call the constructor of Circle implicitly when it is being instantiated. This code doesn’t give any compilation error, unlike the default access modifier example.