Tuesday, March 11, 2014

Understanding Constructors in Java

Hello All,

In this post we will try to understand what a constructor in Java mean.

A constructor is used to create an instance of a class. You can also call this creating an object.

For example : Class1 c = new Class1();

A method basically contains Java statements. It has a signature which constitutes of access modifiers, return type, name and parameters. Just like methods, constructors can also have access modifiers : public, protected, private or none. You can't declare a constructor to be abstract, final, static or synchronized.

Methods can have any return type or even no return type and in this case it is void where as a constructor has no return type, not even void.

Constructors have the same name as their Class name, but a method name can be anything meaningful the method does. A constructor can have 0 or more parameters just like methods.

Now let's consider some scenarios :

public class SubClass{
 
    public static void main(String[] args) {
        SubClass subClass = new SubClass();
    }
}

Here, SubClass subClass statement actually creates an instance of the class SubClass and then new SubClass() creates a new object and the created object is assigned to subClass instance variable.

Here, even if the class don't have a constructor, the java code does not give an error when you compile. The reason is JVM automatically creates an implicit constructor and creates an object of the class.

Consider this case :

public class SubClass{
 
    public static void main(String[] args) {
        SubClass subClass = new SubClass(1);
    }
}

Here, you call a parameterized constructor. We have to have a parameterized constructor defined in the class, otherwise it is not going to compile.

You can create a parameterized constructor like this :

    SubClass(int a) {
    }

Then, JVM uses this parameterized constructor to create an object of the class.

Let's take it to a next level, implementing inheritance.

Let's take 2 classes. SuperClass is a base class and SubClass is a derived class and SubClass has a main method.

Now consider the below example.

class SuperClass {
}

public class SubClass extends SuperClass {
            public static void main(String[] args) {
        SubClass subClass = new SubClass();
    }
}

Now, in the above code, you are calling a default constructor. But, in your java code, you don't have a default constructor defined. JVM implicitly creates a default constructor while running the code and calls it for / while creating an object.

The same above code won't work if you use the following line while creating an object

SubClass subClass = new SubClass(1);

This means you are calling a parameterized constructor but there is no parameterized constructor in the class and the java code won't compile.

If you add the below code to the java class, it would compile and run :

    SubClass(int a) {
           // Your implementation
    }

Now let's consider the actual inheritance where SubClass extends SuperClass. Consider the following code.

class SuperClass {
 
    SuperClass(int a) {
        System.out.println("Inside SuperClass Constructor with one int parameter and a value is : "+a);      
    }
}

public class SubClass extends SuperClass {
 
    SubClass(int a) {
        System.out.println("Inside SubClass Constructor with int parameter and a value is : "+a);
    }
    public static void main(String[] args) {
        SubClass subClass = new SubClass(1);
    }
}

Here in the main method, you are trying to call a parameterized constructor of the child class for creating an object. And you also have a parameterized constructor in the SuperClass. So, while compiling the JVM checks both the SubClass and the SuperClass and since you already declared a parameterized constructor in the SuperClass, the compiler won't take effort in creating a default constructor and expects it to be in class. The above code won't compile. Let me explain why it won't compile.

When creating an object of the SubClass using a parameterized constructor, since the SubClass extends a SuperClass, it either expects you to call the super parameterized constructor in the SubClass parameterized constructor, or declare a default constructor in the SuperClass. If both are ommitted, the code won't compile.

So, below given Code1 or Code 2 would properly compile and give you the output:

Code1 : 

class SuperClass {  
    SuperClass(int a) {
       // Your implementation    
    }
}
public class SubClass extends SuperClass {
       SubClass(int a) {
        super(a);
          // Your implementation and call to the super should always be the first statement
    }
    public static void main(String[] args) {
        SubClass subClass = new SubClass(1);
    }
}

Code2 : 

class SuperClass {

    SuperClass() {
       //Your Implementation
    }
    SuperClass(int a) {
       //Your Implementation
    }
}

public class SubClass extends SuperClass {
   
    SubClass(int a) {
       //Your Implementation
    }
    public static void main(String[] args) {
        SubClass subClass = new SubClass(1);
    }

}

So, what happens in Code1. When you try to create an object of SubClass, it calls the SubClass parameterized constructor and since you already have a call to the SuperClass parameterized constructor in the SubClass parameterized constructor, it would compile and run. The JVM basically also calls the default constructor or expects us to call the parameterized constructor of the SuperClass.

In Code2, as you would have already understood, it makes a call to the default constructor and hence would compile and run the code.

Hope now you got a fair understanding of constructors in Java. Have a great week ahead.