Why Default or No Argument Constructor is Important in Java Class? Answer (original) (raw)
Almost all Java developers know that compiler adds a default constructor or better known as a no-argument constructor in every Java class, but many of them forget that it only does when you don't provide any other constructor. This means it becomes the developers' responsibility to add a no-argument constructor if he is adding an explicit constructor. Now, Why it's important to provide a default constructor in Java, What happens if your class doesn'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 the Spring framework to manage object creation and wiring dependencies, you need to be a bit careful. Many of open source framework, uses reflection to create instance or Object at runtime, based upon the name of the class.
For example, When Hibernate creates an instance of entities using reflection it uses the Class.newInstance() method, which requires a no-argument constructor to create an instance. It's effectively equivalent to the new Entity().
This method throws InstantiationException if it doesn't found any no-argument constructor in the Entity class, and that's why it's advised to provide a no-argument constructor.
Btw, if you are new to the world of Hibernate then I also suggest you go through a hands-on course like these best Hibernate and JPA courses for Java developers. It's a great resource to understand the Hibernate fundamentals and advanced concepts for beginners and experienced java developers.
Effect of not defining Default Constructor in Java
By the way, it's not just Hibernate, who makes use of Reflection to create an instance of the class. If you are familiar with Spring and Dependency Injection, that you might know that Spring also creates an instance of a class using reflection, but it's more sophisticated and allow you to choose which constructor to call by specifying various constructor argument using and 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 the above configuration will create an instance of OrderManager by calling no argument constructor and then use Setter Injection to provided dependency. If you have defined your class like below, then you better use constructor injection to create an instance of this bean.
public class OrderManager{
private SymbolValidator symbolValidator;
public OrderManager(SymbolValidator validator){
symbolValidator = validator;
}
.....
}
The above configuration will show the 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 explicit 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 the 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.