Wednesday, January 15, 2014

Why Default or No Argument Constructor is Important in Java Class

Almost all Java developers knows that compiler adds a default constructor or better known as no argument constructor in every Java class, but many of them forget that, it only does when you don't provide any other constructor. Which means it becomes developers responsibility to add a no argument constructor, if he is adding explicit constructor. Now, Why it's important to provide default constructor in Java, What happens if your class don't have a no argument constructor? Well, this is how it's asked in many Java interviews, most commonly as part of Spring and Hibernate interviews. It's not mandatory to define default constructor, but if you are writing Hibernate persistent class, JPA entities or using Spring framework to manage object creation and wiring dependencies, you need to be bit careful. Many of open source framework, uses reflection to create instance or Object at runtime, based upon name of class. For example When Hibernate creates instance of entities using reflection it uses Class.newInstance() method, which require a no argument constructor to create an instance. It's effectively equivalent of new Entity(). This method throws InstantiationException if it doesn't found any no argument constructor in Entity class, and that's why it's advised to provide a no argument constructor.

Effect of not defining Default Constructor in Java

Why Provide No Argument Constructor in a Java class
By the way it's not just Hibernate, who make use of Reflection to create instance of class. If you are familiar with Spring and Dependency Injection, that you might know that Spring also creates instance of class using reflection, but it's more sophisticated and allow you to choose which constructor to call by specifying various constructor argument using <constructor-arg value="someValue"/> and <constructor-arg ref="someRefrence"/> tags.

How about this code, do you think this will work if Order class doesn't have a no argument constructor?

<bean id="OrderManager" class="com.exchange.OrderManager">
           <property name="symbolValidator" ref="someSymbolValidator"/>

No, it will not work if your OrderManager class has an explicit constructor, because above configuration will create instance of OrderManager by calling no argument constructor and than use Setter Injection to provided dependency. If you have defined your class like below, then you better use constructor injection to create instance of this bean.

public class OrderManager{
    private SymbolValidator symbolValidator;

    public OrderManager(SymbolValidator validator){
         symbolValidator = validator;



Above configuration will show following error :

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'OrderManager' defined in class path resource [app-config.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.exchange.OrderManager]: No default constructor found;

So, You should always define a no argument constructor in your Java class, even if you are writing an explicitly constructor, until you are absolutely sure that, it's won't be instantiated using reflection and instantiating it with no argument constructor is a bug, like in our example of Spring Bean management. Though, In case of Hibernate Persistent classes or Entities, it's must to provide a no argument constructor, so that Hibernate can create instance of Persistence classes, when you hibernate load them from database. It also uses newInstance() method to create instance of persistent classes.


Venkateswarlu konda said...

How we know, java.lang package is default ?

Debjit Saha said...

Using an IDE like Eclipse points out to such issues even before you compile the code. So if you create that parametrized constructor and forget the default constructor, there's Eclipse to come to your rescue!

Peter Lawrey said...

You might like to make a comment about Unsafe.allocateInstance(Class) which doesn't call a constructor.

Anonymous said...

Recently I missed no-argument constructor for a class, which was not final but doesn't implement an interface and don't have a default constructor, because of another parameteric constructor present in the class. Now you can't create mock or dummy version of that class, because
a) it doesn't implement an interface
b) there is no default constructor, means you can't extend it until you use their parametric constructor, which is not possible in case of dummy implementation. This makes testing that class a lot difficult. This teaches me lesson that implement interface and provide no arg constructor alteast.

Anonymous said...

No-argument constructor are evil, it's been promoted by Sun on various stage e.g. in Servlet, Reflection and other places, which leads to brittle and hard to test code. With no argument constructor dependencies are hidden, you don't know what a class need to get it's job done, and you only find it after facing problem. Since there is no class, which can work without being independent on other class, call it collaborators, as professional coder, it's your job to make them obvious. When I look a class, I first see it's constructor, that give me enough idea, what I need to use this class, with this no argument constructor mess, you lose that visibility.

Anonymous said...

You should never write a class with a no argument constructor unless you absolutely must.

That implies the object is mutable, and that its dependencies are set on setters.

That is an anti pattern (though, all too common).

Make classes immutable, use the constructor injection pattern, and your code will be more maintainable, debuggable,

No this does not make it hard to test -- provide the requirements on the constructor (use injection if desired). This is FAR more testable than anything with a no-arg constructor that is mutable.

In short, I agree with the "No-argument constructors are evil" side. I violently agree. I used to be in the other camp, long ago, but have seen the errors in my ways. Making your dependencies explicit, and making things immutable, leads to code that is much easier to debug and test. And radically easier to refactor and maintain.

Post a Comment