Constructor in java is used to create the instance of the class. Constructors are almost similar to methods except for two things - its name is the same as the class name and it has no return type. Sometimes constructors are also referred to as special methods to initialize an object.
Whenever we use new
keyword to create an instance of a class, the constructor is invoked and the object of the class is returned. Since constructor can only return the object to class, it’s implicitly done by java runtime and we are not supposed to add a return type to it. If we add a return type to a constructor, then it will become a method of the class. This is the way java runtime distinguish between a normal method and a constructor. Let’s assume we have following code in Employee
class.
public Employee() {
System.out.println("Employee Constructor");
}
public Employee Employee() {
System.out.println("Employee Method");
return new Employee();
}
Here the first one is a constructor, notice that there is no return type and no return statement. The second one is a normal method where we are again calling the first constructor to get Employee instance and return it. It’s recommended to not have method name same as the class name because it creates confusion.
There are three types of constructor in java.
Let’s look into all these constructor types with example programs.
It’s not required to always provide a constructor implementation in the class code. If we don’t provide a constructor, then java provides default constructor implementation for us to use. Let’s look at a simple program where default constructor is being used since we will not explicitly define a constructor.
package com.journaldev.constructor;
public class Data {
public static void main(String[] args) {
Data d = new Data();
}
}
Constructor without any argument is called a no-args constructor. It’s like overriding the default constructor and used to do some pre-initialization stuff such as checking resources, network connections, logging, etc. Let’s have a quick look at the no-args constructor in java.
package com.journaldev.constructor;
public class Data {
//no-args constructor
public Data() {
System.out.println("No-Args Constructor");
}
public static void main(String[] args) {
Data d = new Data();
}
}
Now when we will call new Data()
, then our no-args constructor will be called. Below image illustrates this behavior, check the console output of the program.
Constructor with arguments is called parameterized constructor. Let’s look at the example of parameterized constructor in java.
package com.journaldev.constructor;
public class Data {
private String name;
public Data(String n) {
System.out.println("Parameterized Constructor");
this.name = n;
}
public String getName() {
return name;
}
public static void main(String[] args) {
Data d = new Data("Java");
System.out.println(d.getName());
}
}
When we have more than one constructors, then it’s constructor overloading in java. Let’s look at an example of constructor overloading in java program.
package com.journaldev.constructor;
public class Data {
private String name;
private int id;
//no-args constructor
public Data() {
this.name = "Default Name";
}
//one parameter constructor
public Data(String n) {
this.name = n;
}
//two parameter constructor
public Data(String n, int i) {
this.name = n;
this.id = i;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "ID="+id+", Name="+name;
}
public static void main(String[] args) {
Data d = new Data();
System.out.println(d);
d = new Data("Java");
System.out.println(d);
d = new Data("Pankaj", 25);
System.out.println(d);
}
}
Note that we can’t use abstract, final, static and synchronized keywords with constructors. However we can use access modifiers to control the instantiation of class object. Using public
and default
access is still fine, but what is the use of making a constructor private? In that case any other class won’t be able to create the instance of the class. Well, a constructor is made private in case we want to implement singleton design pattern. Since java automatically provides default constructor, we have to explicitly create a constructor and keep it private. Client classes are provided with a utility static method to get the instance of the class. An example of private constructor for Data
class is given below.
// private constructor
private Data() {
//empty constructor for singleton pattern implementation
//can have code to be used inside the getInstance() method of class
}
When a constructor calls another constructor of the same class, it’s called constructor chaining. We have to use this
keyword to call another constructor of the class. Sometimes it’s used to set some default values of the class variables. Note that another constructor call should be the first statement in the code block. Also, there should not be recursive calls that will create an infinite loop. Let’s see an example of constructor chaining in java program.
package com.journaldev.constructor;
public class Employee {
private int id;
private String name;
public Employee() {
this("John Doe", 999);
System.out.println("Default Employee Created");
}
public Employee(int i) {
this("John Doe", i);
System.out.println("Employee Created with Default Name");
}
public Employee(String s, int i) {
this.id = i;
this.name = s;
System.out.println("Employee Created");
}
public static void main(String[] args) {
Employee emp = new Employee();
System.out.println(emp);
Employee emp1 = new Employee(10);
System.out.println(emp1);
Employee emp2 = new Employee("Pankaj", 20);
System.out.println(emp2);
}
@Override
public String toString() {
return "ID = "+id+", Name = "+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I have overridden the toString() method to print some useful information about Employee object. Below is the output produced by above program.
Employee Created
Default Employee Created
ID = 999, Name = John Doe
Employee Created
Employee Created with Default Name
ID = 10, Name = John Doe
Employee Created
ID = 20, Name = Pankaj
Notice how one constructor is being called from another constructor, that’s called constructor chaining process.
Sometimes a class is inherited from a superclass, in that case, if we have to call superclass constructor then we can do it using super
keyword. Let’s have a look at an example of using super class constructor. Note that super constructor call should be the first statement in the child class constructor. Also when instantiating child class constructor, java first initializes the super class and then child class. So if the super class constructor is not explicitly called then default or no-args constructor is called by java runtime. Let’s understand these concepts through some example program. Let’s assume we have two classes like below.
package com.journaldev.constructor;
public class Person {
private int age;
public Person() {
System.out.println("Person Created");
}
public Person(int i) {
this.age = i;
System.out.println("Person Created with Age = " + i);
}
}
package com.journaldev.constructor;
public class Student extends Person {
private String name;
public Student() {
System.out.println("Student Created");
}
public Student(int i, String n) {
super(i); // super class constructor called
this.name = n;
System.out.println("Student Created with name = " + n);
}
}
Now if we create a Student object like below;
Student st = new Student();
What will be the output produced? The output of the above code will be:
Person Created
Student Created
So the call went to the no-args constructor of Student class since there was no super call in the first statement the no-args or default constructor of Person class is called. Hence the output. What if we are using parameterized constructor of Student class as Student st = new Student(34, "Pankaj");
, the output will be:
Person Created with Age = 34
Student Created with name = Pankaj
Here the output is clear because we are explicitly calling superclass constructor, so Java doesn’t need to do any extra work from their side.
Java copy constructor takes the object of the same class as an argument and creates a copy of it. Sometimes we need a copy of another object to do some processing. We can do this by following ways:
Now let’s see how to write a copy constructor. Suppose we have a class Fruits
like below.
package com.journaldev.constructor;
import java.util.ArrayList;
import java.util.List;
public class Fruits {
private List<String> fruitsList;
public List<String> getFruitsList() {
return fruitsList;
}
public void setFruitsList(List<String> fruitsList) {
this.fruitsList = fruitsList;
}
public Fruits(List<String> fl) {
this.fruitsList = fl;
}
public Fruits(Fruits fr) {
List<String> fl = new ArrayList<>();
for (String f : fr.getFruitsList()) {
fl.add(f);
}
this.fruitsList = fl;
}
}
Notice that Fruits(Fruits fr)
is performing a deep copy to return the copy of the object. Let’s look at a test program to understand why it’s better to have copy constructor to copy an object.
package com.journaldev.constructor;
import java.util.ArrayList;
import java.util.List;
public class CopyConstructorTest {
public static void main(String[] args) {
List<String> fl = new ArrayList<>();
fl.add("Mango");
fl.add("Orange");
Fruits fr = new Fruits(fl);
System.out.println(fr.getFruitsList());
Fruits frCopy = fr;
frCopy.getFruitsList().add("Apple");
System.out.println(fr.getFruitsList());
frCopy = new Fruits(fr);
frCopy.getFruitsList().add("Banana");
System.out.println(fr.getFruitsList());
System.out.println(frCopy.getFruitsList());
}
}
The output of the above program is:
[Mango, Orange]
[Mango, Orange, Apple]
[Mango, Orange, Apple]
[Mango, Orange, Apple, Banana]
Notice that when copy constructor is used, both the original object and its copy are unrelated to each other and any modifications in one of them will not reflect into other. That’s all for the constructor in java.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Sir in the copy constructor, the code Fruits frCopy = fr; frCopy.getFruitsList(). add ( “Apple” ); We called the getFruitsList,it will return the list and we are adding a fruit.does it affect the object list.Can you explain it?
- Nithya sai
But why are you using this below code ? @Override public String toString() { return "ID = “+id+”, Name = "+name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } what the purpose to write this code in the example… can you please explain ?
- vivek singh
Constructor does not have return type It’s implicit return type is void, but not current class. Constructor is only responsible for initializing object. Object is created and it’s reference is returned by new keyword. For proof you can check constructor bytecode by using javap -verbose command as javap -verbose Example You will find constructor declaration as Example()V --> V stands for void and end of constructor you will find only return–> means returning nothing
- Hari Krishna