A constructor is a special Java method that gets executed when an object of a class is created. It helps in initializing the class object. It also helps in setting the initial values for the object attributes. The primary purpose of a Java constructor is to initialize the recently created object before its usage. In this article, we will be exploring Java constructors.

  1. What is a Constructor
  2. Types of Constructors
  3. Constructor Overloading
  4. Constructor Chaining

Java Constructors

What is a Constructor

As mentioned earlier, a constructor is a special method. It is invoked automatically when an object of a class is created via the new keyword. Java allocates memory for an object when the constructor is invoked. Constructors have some special properties. The name of the constructor is the same as the class name. Also, constructors do not have a return type. Constructors are typically used to specify code that needs to be executed as soon as an object of a class is created. This includes setting the instance fields to some default values, invoking the super-class constructor, etc.

All of the classes have constructors by default. Moreover, if the user does not create a class constructor, Java creates a constructor for the user. The only catch here is that the user will no longer set initial values for the object attributes.

Defining Constructor in Java

Following is a very simple example of defining a constructor in Java:

public class TestClass {
       public TestClass() {
       }
}

The very first part of declaring any Java constructor is the access modifier. The access modifier is similar to the methods and fields in Java. It determines the limitation of accessing the constructor. These access modifiers could be public, private, protected, or default. Moreover, the second part of the constructor declaration is the class’s name to which the constructor belongs. The third part of the constructor is the parameters it can take. Parameters are the key to differentiating between the default constructor and the parameterized constructor. Lastly, the fourth part is the body of the constructor.

Types of Constructors

Java supports two types of constructors, default and parametrized. Let us take a look at these two.

Default Constructor

A default constructor is a constructor that does not accept any arguments. It is also known as a no-arguments constructor. It is not mandatory to provide a default constructor. If a default constructor is not provided, Java automatically adds a default constructor.

Therefore, a call will always possess at least one default constructor at the time of compilation. However, if the user provides the Java class with a customized constructor, the Java compiler will no longer insert the default constructor for the class.

Code Sample


public class Book {

  String name;
  int numPages;

  public static void main(String args[]) {
    Book book1 = new Book();
    System.out.println("Book "+book1.name+" has "+book1.numPages+" pages");
  }
}

  • Line 1 specifies a class called Book. It has instance fields corresponding to name and numPages
  • The Book class does not have any constructor so Java automatically adds a constructor
  • Line 6 specifies the main method
  • Line 7 creates a new Book object. This causes the default constructor added by Java to be invoked.

Output

Book null has 0

Since the default constructor provided by Java is used, it does not do anything, the name and numPages fields are not initialized.

Developers can also explicitly specify a default constructor. In this case, Java does not add another default constructor of its own and the specified default constructor gets invoked when an object of the class is created.

Code Sample


public class Book {

  String name;
  int numPages;

  public Book() {
    name = "Learn Java";
    numPages = 250;
  }

  public static void main(String args[]) {
    Book book1 = new Book();
    System.out.println("Book "+book1.name+" has "+book1.numPages+" pages");
  }
}

  • This code also specifies a class called Book
  • Line 6 explicitly specifies a default constructor. As mentioned earlier, the name of the constructor is the same as the class name and it does not have a return type.
  • Lines 7,8 initializes the name and numPages fields with some values
  • When Line 12 is executed, the default constructor at Line 6 is invoked.

Output

Book Learn Java has 250 pages

Parameterized constructor

A parameterized constructor is a constructor that accepts some parameters. Any number of parameters can be specified. Parameterized constructors are mostly used to initialize the instance fields of a class.

Code Sample


public class Book {

  String name;
  int numPages;

  public Book(String name, int numPages) {
    this.name = name;
    this.numPages = numPages;
  }

  public static void main(String args[]) {
    Book book1 = new Book("Learn Java",250);
    System.out.println("Book "+book1.name+" has "+book1.numPages+" pages");
  }
}

  • Line 6 specifies a Book constructor. It accepts a String parameter called name and an int parameter called numPages
  • Lines 7,8 initialize the instance fields with the values passed in
  • Line 12 creates a new Book object. It specifies the values “Learn Java” and 250. This causes the constructor at Line 6 to be invoked with these values.

An interesting thing to note here is the use of “this” in the field initialization step. The reason is that a Java constructor can accept the same parameter names as the class fields. However, there could be a problem for the Java compiler in referring to the correct one when the parameter and field have the same name. Therefore, the parameter acts as a shadow of the field having the same name. So, there is a good chance of misplacing the provided value with the original one. Providing “this.” to the compiler resolves this confusion.

Output

Book Learn Java has 250 pages

An important point to note is that once a parameterized constructor is specified in a class, Java cannot automatically insert a default constructor.

Consider the following code:


public class Book {

  String name;
  int numPages;

  public Book(String name, int numPages) {
    this.name = name;
    this.numPages = numPages;
  }

  public static void main(String args[]) {
    Book book1 = new Book();
    System.out.println("Book "+book1.name+" has "+book1.numPages+" pages");
  }
}

  • Book class has a parameterized constructor specified at Line 6
  • Line 12 tries to create a Book object with the default constructor
  • Since a parameterized constructor is already present, Java cannot add the default constructor
  • So, Line 12 causes a compilation error

Constructor Overloading

Java supports method overloading whereby a class can have more than one method with the same name but a different type/number of parameters. Since constructors are special methods, they can also be overloaded. So a class can have multiple constructors that accept different types/numbers of parameters.

Code Sample


public class Book {

  String name;
  int numPages;

  public Book() {
    this.name = "Default";
    this.numPages = 0;

  }

  public Book(String name, int numPages) {
    this.name = name;
    this.numPages = numPages;
  }
}

  • Line 6 specifies a default constructor. It does not accept any arguments and simply assigns some default values to the name, numPages fields
  • Line 12 specifies a parameterized constructor. It accepts two arguments and assigns these values to the name and numPages fields

Constructor Chaining

Constructor chaining occurs when a constructor is invoked from another constructor. The constructor is invoked can be in the same class or a superclass.

Invoking Constructor in the same class

A constructor can invoke another constructor within the same class via this keyword. The call to the constructor must be the first statement in the class.

Code Sample

public class Employee {

  String name;
  double salary;
  String department;

  public Employee(String name,double salary,String department) {
    this.name= name;
    this.salary= salary;
    this.department = department;
  }

  public Employee(String name,String department) {
    this(name, 0, department);
  }
}

  • Line 1 defines an Employee class. It has instance fields corresponding to name, salary, and department
  • Line 7 specifies a constructor that accepts name, salary, and department as parameters and initializes the instance fields with the values passed in
  • Line 13 specifies a constructor that accepts parameters corresponding to only name and department. It invokes the constructor at Line 7 via this keyword by passing a default value of 0 for salary.

Invoking super-class constructor

There is a property in Java that allows a class to extend to another class. This extension allows the class to inherit from the extended class. A sub-class is the one that extends the other class, and the extended class is the super-class.

By default, when a subclass object is created, it automatically invokes the super-class constructor before executing the code within the sub-class constructor.

Code Sample

public class Animal {

  public Animal() {
    System.out.println("In animal constructor");
  }

 }
 
 public class Mammal extends Animal{
   public Mammal() {
     System.out.println("In mammal constructor");
  }

  public static void main(String args[]) {
   Mammal mammal = new Mammal();
  }
}

  • Line 1 defines an Animal class. It has a constructor that simply prints some text
  • Line 9 specifies a Mammal class. It is a subclass of Animal. It also has a constructor that prints some text
  • Line 15 creates a Mammal object. This causes the Mammal constructor to be invoked. Since Mammal is a sub-class of Animal, the Animal constructor is invoked automatically.

Output

In animal constructor
In mammal constructor

A sub-class constructor can also explicitly invoke the base class constructor. The super keyword is useful for this. This is particularly useful when there are multiple constructors or parameterized constructors in the base class.

Sample Code

public class Animal {

  public Animal() {
    System.out.println("In animal constructor");
  }
  
  public Animal(String name) {
    System.out.println("In second Animal constructor ");
    System.out.println("Animal is a "+name);
  }
}

public class Mammal extends Animal{

  public Mammal() {
    super("Dog");
    System.out.println("In mammal constructor");
 }

 public static void main(String args[]) {
   Mammal mammal = new Mammal();
 }
}

  • The Animal class has two constructors. The constructor at Line 3 does not accept any arguments while the constructor at Line 7 accepts a name as an argument.
  • The Mammal constructor invokes the Animal constructor at Line 7 via the super keyword and passes an animal name
  • If the call to super is removed, the default Animal constructor at Line 3 will get invoked

Output

In the second Animal constructor
Animal is a Dog
In mammal constructor

Access Modifiers of Java Constructors

Access modifiers help in determining which classes in the application are allowed to call the constructor. For example, if the access modifier is “protected,” then only the classes in the same package and the subclasses of that class can access the constructor. Moreover, if a class has multiple constructors, then every constructor can have its access modifier. Therefore, the access to such constructors depends on the limitation according to their access modifiers.

Conclusion

So, in this article, we took a look at Java constructors. We understood what a constructor is and how it can be used to execute some initialization code. We saw the different types of constructors and understood the difference between default and parameterized constructors. We also saw how constructors can be overloaded. Finally, we saw how constructors can be chained.