Constructors Overview

Photo by Aaron Huber on Unsplash

Constructors Overview

Constructors in Java

What are constructors?

Constructors are specialized setter methods that have the same name as that of the class.

class Student{
    private int age;
    private String name;

    Student(){
        System.out.println("This is a constructor with zero parameters.");
    }
    Student(int a){
        System.out.println("This is a constructor with one parameter.");
    }
}

In the above example, we can see two constructors (methods with the same name as that of the class), having the name Student within the Student class, one takes zero arguments and the other takes one integer argument.

These can or cannot have any parameters. You can choose to add an access specifier to it, it's not necessary, but you cannot assign a return type. If no constructor has been defined in the class, a default construct will be added to the class by the JVM.

Our next question is that in the above code snippet if both the constructors have the same name (Student and Student), how will the compiler decide which one to execute? and why do we even need to create these constructors in the first place? let's tackle one question at a time.

Why do we need Constructors?

Constructors are called at the time of object creation with the 'new' keyword to initialize the instance variables with a default value or to initialize them with the value we require to initialize them with.

Object obj = new Object(). Here, Object() is a constructor of the Object class, which is being used to initialize the instance variable with default values.

Object obj = new Object("Data"). Here, Object("Data") is a constructor of the Object class, which is being used to initialize the instance variable with a String value.

Let us try to understand both scenarios further by writing some code snippets and observing the results.

Working of constructors:

  1. Class with no constructor:

    In this case, we have not added any constructor in the class body, yet the values have been initialized with default values, why? because at the time of loading the class, JVM includes the default constructor which initializes the references with default values.

    Note: The default constructor is Zero parameterized.

     class Student{
         private int age;
         private String name;
    
         void result(){
             System.out.println("The Age is : " + age + " and name is : " + name);
         }
     }
    
     public class MyTest{
         public static void main(String []args){
             Student obj = new Student();
             obj.result();
         }
     }
    

    Output:

     [Running] cd "/config/workspace/" && javac MyTest.java && java MyTest
    
     The Age is : 0 and name is : null
    
     [Done] exited with code=0 in 0.775 seconds
    
  2. Class with a constructor with no parameters:

    In this case, we added a zero parameterized constructor in the class body, let's observe what the output comes out to be.

     class Student{
         private int age;
         private String name;
    
         Student(){
         }
         void result(){
             System.out.println("The Age is : " + age + " and name is : " + name);
         }
     }
    
     public class MyTest{
         public static void main(String []args){
             Student obj = new Student();
             obj.result();
         }
     }
    

    Output:

     [Running] cd "/config/workspace/" && javac MyTest.java && java MyTest
    
     The Age is : 0 and name is : null
    
     [Done] exited with code=0 in 0.794 seconds
    

    As you can see, the age and name references have been initialized with default values 0 and null*,* when we created a constructor with zero parameters in the class.

  3. Class with a constructor which takes an integer and a String value as parameters:

    For this case, we have added a parameterized constructor in the class body, let us now observe what happens in this case.

     class Student{
         private int age;
         private String name;
    
         Student(int age, String name){
             this.age = age;
             this.name = name;
         }
    
         void result(){
             System.out.println("The Age is : " + age + " and name is : " + name);
         }
     }
    
     public class MyTest{
         public static void main(String []args){
             Student obj = new Student(55,"BABU RAO");
             obj.result();
         }
     }
    

    Output:

     [Running] cd "/config/workspace/" && javac MyTest.java && java MyTest
    
     The Age is : 55 and name is : BABU RAO
    
     [Done] exited with code=0 in 0.806 seconds
    

    As we can see in the above snippet, at the time of object creation itself, we have passed the value to the constructor and it has set the values for the private references.

    Note: Since we have created a constructor in our class, it doesn't matter with or without parameters. Once a constructor is created in that class, no default constructor will be added by default.

    If we try to execute it without providing the required arguments, it results in a runtime error with the error message: The constructor is undefined.

Class with two or more constructors:

This is the point, where we need to discuss what is Constructor Overloading.

With the same concept as method overloading, When multiple constructors have the same name as that of the class, then the compiler matches the parameters with the arguments provided while calling the constructor (creating the object) and executes that particular matched constructor.

If no match is found it gives the error message: The constructor is undefined.

Let's understand this as well with a code snippet,

class Student{
    private int age;
    private String name;

    Student(){
        System.out.println("Constructor with zero parameters");
    }

    Student(int age, String name){
        this.age = age;
        this.name = name;
        System.out.println("Constructor with int and String params");
    }

    void result(){
        System.out.println("The Age is : " + age + " and name is : " + name);
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj = new Student();
        Student obj1 = new Student(55,"BABU RAO");
    }
}

Output:

[Running] cd "/config/workspace/" && javac MyTest.java && java MyTest

Constructor with zero parameters
Constructor with int and String params

[Done] exited with code=0 in 0.802 seconds

So, here we can observe that:

  1. First, the constructor with zero parameters was called when 'obj' was created with zero arguments as it matched the zero-parameterized initialization.

  2. Then the second constructor was called when 'obj1' was created with two arguments as it matched the constructor with two parameters.

    Note: If arguments of different types were given or the number of arguments didn't match any existing constructor's numbers of parameters, it would have ended with an error message: The constructor is undefined.

This() and Super() method.

The next in line for discussion while discussing about the constructor is the super() method calling and this() method calling.

If you have been working with objects, you would have noticed that even though you do not specify some properties or methods in classes, as soon as you create an object from them, those objects are already having some properties by default.

No, we are not talking about default classes, we are discussing the classes you create.

Go ahead and give it a try now. Create any class and then create an object of it. you will see methods in it that you have not defined as part of your class, Observe the example snippet below,

So how do these come? These are inherited properties.

But we have not inherited any class? Then? How? It is happening because all classes by default inherit the Object class. We will go through Inheritance at a later stage.

Right now, what we need to understand, is that when an object of any class is created its constructor is called and while its constructor is called, the constructor of its parent class is called in it and it executes first then only the child class constructor is executed, if it doesn't make any sense, we hope below will give you some clarity.

  1. If a method of the same class is to be called, then we use this() method as the first line of the method, In the below example code snippet, we added this() method in the first line of the parameterized constructor then created an object of it in the main function. Let us observe how the output comes out to be:
class Student{
    private int age;
    private String name;

    Student(){
        System.out.println("Constructor with zero parameters");
    }

    Student(int age, String name){
        this();
        System.out.println("Constructor with int and String params");
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj1 = new Student(55,"BABU RAO");
    }
}

Output:

[Running] cd "/config/workspace/" && javac MyTest.java && java MyTest

Constructor with zero parameters
Constructor with int and String params

[Done] exited with code=0 in 0.802 seconds

As observed, Even though we didn't specifically call the zero-parameterized constructor it is being called as we have specified this() method at the first line of our constructor. First, it will execute the zero-parameterized constructor and then the lines after it.

  1. The calling of the parent class constructor is done by the super() method. In our next example. We have class Student which is extending to class Hooman. We have replaced our this() method with the super() method now. Let's proceed with observing the output.
class Hooman{
    Hooman(){
        System.out.println("\nHey, I am HOOMAN.\n");
    }
}
class Student extends Hooman{
    private int age;
    private String name;

    Student(){
        System.out.println("Constructor with zero parameters");
    }

    Student(int age, String name){
        //this();
        super();
        System.out.println("Constructor with int and String params");
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj1 = new Student(55,"BABU RAO");
    }
}

Output:

[Running] cd "/config/workspace/" && javac MyTest.java && java MyTest

Hey, I am HOOMAN.

Constructor with int and String params

[Done] exited with code=0 in 0.802 seconds

So, here as observed, Even though we didn't specifically call the parent class constructor it is being called as we have specified the super() method at the first line of our constructor. First, it will execute the parent class constructor and then the lines after it.

Note: The first line of a method should either contain Super() or this() method, if no method is specified, by default it Super() method.

Conclusion

In this article, we have seen what are constructors and how they work, how you call them, what is method overloading and what is the role of super and this method, I have tried to keep the content concise, hope it made sense to you all!!



Thanks for coming this far in the article, I Hope I was able to explain the concept well enough. If in any case, you face any issues please feel free to reach out to me, I'd be happy to help.

You can always connect to me over LinkedIn to share feedback or queries by clicking here -->> Connect with me on LinkedIn.