Wednesday, October 22, 2014

Why Constructor is Important in Java

In simple word, Constructor is a method like block of code which is called by Java runtime during object creation using new() operator. Constructor are special in 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 object. Have you ever thought about Why do you need 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 it's 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 add lot on readability and usability of class. 
When you create 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 makes 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 it's 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 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 same name) until they have different method signature, which comprise type of argument and order type of argument. Here is an example of constructor overloading. Here we have three constructor but all with 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 top and gradually putting constructor in increasing order of argument as shown above. This also flows nicely when you call one constructor from other. You can see example of overloaded constructor in JDK also, for example String class got coupled of overloaded constructor, 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 constructor from same class or parent class. By default every constructor call their parent class' no argument constructor in 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 parameter, if you don't pass any parameter they will call default constructor with no argument, if you have defined constructor which accepts parameter you can call them by passing parameter of same type. Your this() or super() constructor invocation must match with corresponding constructor in same or parent class. It is one of the popular way 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 same name as Class they belong to
This is 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 compile will treat them as constructor and since constructor cannot have return type, but 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 is executed before 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 constructor of that class, but only after successful execution of constructor from super class. If your parent class constructor throw exception then instance initialization block will not execute.

8. Super class constructor is executed before sub class
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 get executed. This is 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 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. Constructor can not be final, abstract or synchronized.
These modifiers are illegal to be used with constructor, so don't try them. Understanding why constructor cannot be final, abstract or synchronized require to learn Java specification. It's something nice to explorer 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 constructor, this will result in compile time error. This is one of the major difference which differentiate a regular method to a constructor in Java.


That's all about Constructor in Java. We have learned why constructor is important and how they work in Java. we also have learned lot of special things about constructor e.g. they must have 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 constructor, I am from that second group. IMHO constructor highlights dependency better than Setter injection and it also enforce order of initialization. In fact using constructor has become easier now days because you can use dependency injection to initialize your classes. If you use open source IOC container like Googel Guice or Spring framework, it would be very easy to use and test class with proper constructor.  I am ready to go with constructor just for the fact that a class with constructor highlighting it's dependency is much more readable then the one which is initialized by setter methods.