Constructor in Java

Filed Under: Java
Java Constructor

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.

Constructor in Java

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.

Types of Constructor in Java

There are three types of constructor in java.

  1. Default Constructor
  2. No-Args constructor
  3. Parameterized constructor

Let’s look into all these constructor types with example programs.

Default Constructor in Java

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();
	}
}
  1. Default constructor only role is to initialize the object and return it to the calling code.
  2. Default constructor is always without argument and provided by java compiler only when there is no existing constructor defined.
  3. Most of the time we are fine with default constructor itself as other properties can be accessed and initialized through getter setter methods.

No-Args Constructor

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.

no args constructor in java

Parameterized Constructor

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());
	}

}

java class constructor with parameters

Constructor Overloading in Java

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);
		
	}

}

Private Constructor in Java

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
}

Constructor Chaining in Java

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.

Java Super Constructor

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

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:

  1. implement cloning
  2. providing a utility method for deep copy of the object.
  3. Having a copy constructor

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.

Comments

  1. Hari Krishna says:

    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

    1. Anton says:

      Wow. Perfect answer man. For those who are interested in knowing things clearly and deep, this answer helps. Good

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages