Constructors in Java
Constructors are one of the most fundamental concepts in Java and play a critical role in Object-Oriented Programming. Every time an object is created in Java, a constructor is involved either directly or indirectly. Constructors are responsible for initializing objects and preparing them for use. Without constructors, objects may remain incomplete or contain default values that are not meaningful for real-world applications. Understanding constructors deeply is extremely important because constructors are used extensively in enterprise applications, frameworks like Spring Boot, Hibernate entities, dependency injection, APIs, and object creation patterns.
A constructor in Java is a special type of method that is automatically executed when an object is created. Its main purpose is to initialize object state by assigning values to instance variables. Unlike normal methods, constructors do not have any return type, not even void. The constructor name must always be exactly the same as the class name.
Example:
class Student {
int id;
String name;
Student() {
System.out.println("Constructor Called");
}
}
public class Demo {
public static void main(String[] args) {
Student s = new Student();
}
}
Output:
Constructor Called
In this example, when the object s is created, the constructor executes automatically. This demonstrates the primary behavior of constructors in Java.
Constructors were introduced because objects need proper initialization at the time of creation. Suppose a Student object is created without assigning values to important fields such as id or name. The object would contain meaningless default values like 0 or null. Constructors solve this problem by ensuring objects are initialized properly during creation itself.
One important rule about constructors is that they are called automatically by the JVM when an object is created using the new keyword. Developers do not call constructors explicitly like normal methods. The new keyword internally performs several operations:
- memory allocation,
- object creation,
- constructor invocation,
- object reference assignment.
This entire process happens automatically.
Java provides different types of constructors based on initialization requirements.
The first type is the:
Default Constructor
A Default Constructor is a constructor provided automatically by the compiler when the programmer does not create any constructor explicitly. It does not accept parameters and initializes instance variables with default values.
Example:
class Employee {
int id;
String name;
}
public class Demo {
public static void main(String[] args) {
Employee e = new Employee();
System.out.println(e.id);
System.out.println(e.name);
}
}
Output:
0
null
Here, the compiler automatically creates a default constructor because no constructor was written manually.
However, once a programmer defines any constructor explicitly, the compiler no longer provides the default constructor automatically.
Example:
class Employee {
Employee(int id) {
System.out.println(id);
}
}
public class Demo {
public static void main(String[] args) {
Employee e = new Employee();
}
}
This code produces a compilation error because the default constructor no longer exists.
The second important type is the:
Parameterized Constructor
A Parameterized Constructor accepts arguments and allows objects to be initialized with custom values during creation.
Example:
class Student {
int id;
String name;
Student(int i, String n) {
id = i;
name = n;
}
void display() {
System.out.println(id + " " + name);
}
}
public class Demo {
public static void main(String[] args) {
Student s1 = new Student(101, "Venky");
Student s2 = new Student(102, "Ravi");
s1.display();
s2.display();
}
}
Output:
101 Venky
102 Ravi
Parameterized constructors are heavily used in real-world applications because they ensure objects are created with meaningful data.
Another important type is the:
Copy Constructor
Java does not provide built-in copy constructors like C++, but developers can create them manually. A Copy Constructor creates a new object using values from another object.
Example:
class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
Student(Student s) {
this.id = s.id;
this.name = s.name;
}
void display() {
System.out.println(id + " " + name);
}
}
public class Demo {
public static void main(String[] args) {
Student s1 = new Student(101, "Venky");
Student s2 = new Student(s1);
s2.display();
}
}
Output:
101 Venky
Copy constructors are useful when duplicate objects need to be created safely.
One of the most important keywords related to constructors is:
this
The this keyword refers to the current object. It is commonly used to differentiate instance variables from local variables when both have the same names.
Example:
class Employee {
int id;
String name;
Employee(int id, String name) {
this.id = id;
this.name = name;
}
void display() {
System.out.println(id + " " + name);
}
}
Without this, Java would become confused between constructor parameters and instance variables.
Constructors can also call other constructors within the same class using:
this()
This concept is called:
Constructor Chaining
Example:
class Demo {
Demo() {
this(100);
System.out.println("Default Constructor");
}
Demo(int x) {
System.out.println("Parameterized Constructor");
}
}
public class Main {
public static void main(String[] args) {
Demo d = new Demo();
}
}
Output:
Parameterized Constructor
Default Constructor
Constructor chaining improves code reuse and reduces duplication.
Constructors also participate in inheritance. When a child object is created, the parent constructor executes first. Java uses the super() keyword internally to invoke parent constructors.
Example:
class Parent {
Parent() {
System.out.println("Parent Constructor");
}
}
class Child extends Parent {
Child() {
System.out.println("Child Constructor");
}
}
public class Demo {
public static void main(String[] args) {
Child c = new Child();
}
}
Output:
Parent Constructor
Child Constructor
This happens because Java ensures parent initialization before child initialization.
Constructors can have access modifiers such as:
- public,
- private,
- protected,
- default.
Private constructors are especially important in:
- Singleton Design Pattern,
- Utility classes,
- Factory methods.
Example of Singleton:
class Singleton {
private static Singleton obj = new Singleton();
private Singleton() {
System.out.println("Object Created");
}
public static Singleton getInstance() {
return obj;
}
}
Here, private constructor prevents external object creation.
One important rule is that constructors cannot:
- be static,
- be final,
- be abstract,
- be inherited,
- return values.
This is because constructors belong specifically to object creation.
Another important interview topic is:
Difference between Constructor and Method
| Constructor | Method |
|---|---|
| Initializes object | Performs operations |
| Same name as class | Any valid name |
| No return type | Can return values |
| Called automatically | Called explicitly |
| Executes once per object | Can execute many times |
Constructors are heavily used in modern frameworks like Spring Boot and Hibernate. In Spring:
- constructors are used for Dependency Injection,
- beans are initialized using constructors.
Example:
@Service
public class UserService {
private UserRepository repo;
public UserService(UserRepository repo) {
this.repo = repo;
}
}
This is called:
Constructor Injection
which is one of the most recommended dependency injection approaches in Spring Boot.
Hibernate also requires:
No-Argument Constructor
for entity creation through reflection.
Example:
@Entity
class Student {
@Id
private int id;
public Student() {
}
}
Without default constructors, Hibernate fails to create objects dynamically.
From an interview perspective, constructors are one of the most frequently asked topics. Common interview questions include:
- Why constructors are needed?
- Can constructors be overridden?
- Difference between constructor and method?
- Why constructors cannot be static?
- What is constructor chaining?
- What is copy constructor?
- Why Hibernate requires default constructor?
- Difference between
this()andsuper()?
The primary purpose of constructors is to ensure that objects are initialized properly and safely at the time of creation. Constructors improve code organization, maintainability, object consistency, and encapsulation. They are deeply integrated into Java’s object creation mechanism and form one of the foundational concepts of Object-Oriented Programming.
A strong understanding of constructors is extremely important for backend developers because constructors are used extensively in enterprise frameworks, dependency injection, ORM tools, object-oriented design patterns, and modern Java application development.