Why Constructor is Important in Java

In simple word, Constructor is a method like a block of code which is called by Java runtime during object creation using new() operator. Constructor are special in the sense that they have the same name as the Class they are part of. They are also special in a sense that they are called by JVM automatically when you create an object. Have you ever thought about Why do you need a constructor? What benefits it provide? One reason is to initialize your object with default or initial state since default values for primitives may not be what you are looking for. One more reason you create constructor is to inform the world about dependencies, a class needs to do its job. Anyone by looking at your constructors should be able to figure out, what he needs in order to use this class.  For example, following class OrderProcessor needs a Queue and Database to function properly.


class OrderProcessor{
    Database to;
    Queue from;
    
    public OrderProcessor(Queue source, Database target){
        this.from = source;
        this.to = target;
    }
    
    public void process(Message msg) {
        // read from Queue
        // put to database
    }
    
}
This itself state importance of Constructor, it adds lot on readability and usability of class. When you create an object of OrderProcessor class e.g. new OrderProcessor(myQueue, myDatabase), JVM will call this constructor. If you don't add any constructor Java by default add a default no argument constructor in your class. Constructors also make it easy to test a class because fundamentally they follow Dependency Injection. 

It's easy to create a MockQueue and MockDatabase to test our OrderProcessor class, consider what would happen if this class is calling a Singleton or Service method to get its dependency. It would be difficult to test that class. Since object creation is a fundamental concept, every Java developer should know how Constructor works, how they initialize an object, how a super class constructor is called and so on. In Next section, we will see how that happens.




How Constructor Works in Java

Constructor is special, they contain a block of code, which executed when you create object using new operator. If your class has a super class or parent class then it's constructor will be executed before your class. Similarly, if you have more than one constructor in your class, you can call them from your constructor. while calling constructor always remember that call must be the first line in constructor, as shown in following example :
public OrderProcessor(Queue source, Database target){
        this.from = source;
        this.to = target;
    }
    
    public OrderProcessor(){
        this(defaultQueue, defaultDatabase);
    }
Here no argument constructor is calling constructor which accept a Queue and Database. This is known as constructor chaining and you use this() and super() to call constructor from same class and parent class respectively. You can use public, private, protected access modifier with constructor or can even leave them without any parameter in that case it will use default access, which is at package-private level. Private constructor are special, because if you make your constructor private, then no one can call it from outside that class, which means no external way to create instance of that class. This also prevents a class from being subclasses because by default first line of constructor has a call to super(), no argument constructor of parent class, if you make that private, it will not be accessible on child class and compiler will throw error. Private constructor has another special use, in singleton design pattern, where goal is to keep just one instance of that class. Singleton creates instance by itself, caches it and provides a getInstance() method to make that instance available to outside world.
UnLike C++ Java doesn't have any destructor, instead it has finalize method, which is called just before Garbage collector reclaim an eligible object. Also, you cannot make constructor abstract, synchronized or final, those are illegal keyword for constructor and using them there will be error at compile time.  

Some facts about Constructor in Java

There are lot facts about constructor you as a Java developer should know, this will help you to read and understand existing Java code in your organization or from any open source library.

1. Constructor can be overloaded
This means you can have more than one constructor in your class (all with the same name) until they have different method signature, which comprises type of argument and order type of argument. Here is an example of constructor overloading. Here we have three constructors but all with a different set of parameters, make sure you follow these overloading best practices to avoid introducing tricky bugs in your code.
public OrderProcessor(){
        this(defaultQueue, defaultDatabase);
    }
    
    public OrderProcessor(Queue source, Database target){
        this.from = source;
        this.to = target;
    }
    
    public OrderProcessor(Queue source, Database target, long timeout){
        this.from = source;
        this.to = target;
        this.timeout = timeout;
    }

It's better to put no argument constructor at the top and gradually putting a constructor in the increasing order of argument as shown above. This also flows nicely when you call one constructor from other. You can see the example of overloaded constructor in JDK also, for example, String class got a couple of the overloaded constructors, just look their Java documentation.

Constructor in Java, what why and how
2. Constructor can be chained
Calling one constructor from other is known as Constructor chaining. You can call a constructor from same class or parent class. By default, every constructor calls their parent class' no-argument constructor in the first line e.g super().

3. Call Constructor using this() and super()
You can invoke parent class' constructor using super() and same class constructor using this(). Pay attention to the parameter, if you don't pass any parameter they will call default constructor with no argument if you have defined a constructor which accepts parameter you can call them by passing a parameter of the same type. You're this() or super() constructor invocation must match with the corresponding constructor in same or parent class. It is one of the popular ways to use this keyword in Java.

4. Constructor is not inherited in Java
This is an interesting but non-obvious information about constructor. When you create a child class in Java, it inherits member variables, non-final and non-static methods but not constructors. They belong to the class they are declared.

5. Constructor should have the same name as Class they belong to
This is a paramount requirement, in fact, this is how you recognize a constructor and how you differentiate a constructor with a regular method. Any method in Java cannot have the same name as their class because then the compiler will treat them as a constructor and since constructor cannot have a return type, but the method must have, they will throw compile time error.

6. Constructor doesn't have return type
This is another difference between a regular method and constructor, it cannot have a return type, not even void. Any attempt to put return type will result in compile time error.

7. Static initializer and instance initializer block are executed before the constructor.
If you don't know how a class is loaded and initialize, read this. Apparently static initializer is executed at the time of class loading and instance initializer block of a class is executed before the constructor of that class, but only after successful execution of constructor from the super class. If your parent class constructor throws an exception then instance initialization block will not execute.

8. Super class constructor is executed before subclass
This is true, you can verify this by creating a class hierarchy of father and son, here is an example , you can see that message from Father's executed is printed before Son constructor gets executed. This is a natural right, Father comes before Son.
public class Test {

    public static void main(String args[]){
        Son mySon = new Son();  // call Father() first then Son()            
    }
}

class Father {
    
    Father(){
        System.out.println("Hello Father");
    }
}

class Son extends Father {
    Son(){
        System.out.println("Hello Son");
    }
}

Output
Hello Father
Hello Son


9.  Construct invocation must be in fist line
If  you explicitly called another constructor from same class or parent class it must be the first line of calling the constructor. As I said earlier, by default every constructor call super(), no argument constructor parent class. By the way, this is something compiler will not let you forget so not to worry about it :-)

10. A constructor can not be final, abstract or synchronized.
These modifiers are illegal to be used with a constructor, so don't try them. Understanding why constructor cannot be final, abstract or synchronized require learning Java specification. It's something nice to explore yourself.

11. Consider providing No argument constructor 
Even if you add a parametric constructor, consider adding a no-argument constructor if your class is intended to be used by reflection or by a framework e.g. Hibernate, which requires their entity classes to have a no argument constructor so that framework can create their object, to learn more about why default constructor is important for a class, see that link.

12. Constructor doesn't return anything
You can not use any return type including void with the constructor, this will result in compile time error. This is one of the major difference which differentiates a regular method to a constructor in Java.


That's all about Constructor in Java. We have learned why the constructor is important and how they work in Java. we also have learned a lot of special things about constructor e.g. they must have the same name, they cannot have return type or constructor cannot be made abstract, final or synchronized. In today's framework world there is always debate about constructor vs setter injection. There is two group of people, one who likes setter based injection and other who are purist and use a constructor, I am from that second group. IMHO constructor highlights dependency better than Setter injection and it also enforces order of initialization. In fact using constructor has become easier nowadays because you can use dependency injection to initialize your classes. If you use open sources IOC containers like Google Guice or Spring framework, it would be very easy to use and test class with the proper constructor.  I am ready to go with constructor just for the fact that a class with constructor highlighting its dependency is much more readable than the one which is initialized by setter methods.



5 comments:

  1. 12. Constructor doesn't return anything

    I though that constructor returns instance of a new object.

    ReplyDelete
    Replies
    1. constructor doesn't have a return type which means it doesn't return anything. Object is created in address and its reference is assigned to the reference variable.

      Delete
  2. what you think about when i call super(); ^ ^

    ReplyDelete
  3. Why we use constructor ... i am beginner in java i cant understand why we use constructor.. instead we can create a object by using new keyword itself na???
    is there any reason for using constructor instead of creating a object with new keyword

    ReplyDelete
  4. is it always true that when a constructor is called,object is made.

    ReplyDelete