Constructors in Java

  • Last Updated: April 20, 2025
  • By: javahandson
  • Series
img

Constructors in Java

Understand constructors in Java, their types, overloading, rules, and how they differ from static blocks with examples to enhance your Java coding skills.

 

A constructor in Java is a special type of method that is used to initialize objects. It is automatically called when an object of a class is created. The primary purpose of a constructor is to initialize the instance variables of a class.

Key Characteristics of a Constructor

1. It has the same name as the class.
2. It does not have a return type (not even void).
3. It is invoked automatically when an object is created.

Importance of Constructors

1. Constructors allow automatic initialization of objects when they are created, reducing the need for explicit method calls.
2. They prevent the creation of objects in an uninitialized state by enforcing necessary values through constructor parameters.
3. Makes code cleaner by ensuring proper initialization inside the constructor itself.

Types of Constructors in Java

Constructors are categorized into 3 types:

1. Default Constructor (No-Argument Constructor)
2. Parameterized Constructor
3. Copy Constructor (User-defined, not built-in)

Default Constructor (No-Argument Constructor)

A default constructor is a type of constructor that does not take any arguments. If no constructor is explicitly defined in a class, Java automatically provides a default constructor.

Syntax

class ClassName 
{
    // Default constructor

    ClassName() 
    {
        // Initialization code
    }
}

Write a program to explicitly define a default constructor.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    // Default Constructor
    public Student() {
        this.name = "Suraj";
        this.rollNumber = 101;
    }

    public static void main(String[] args) {
        Student student = new Student();
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);
    }
}
Output:
Student Name : Suraj
Student Roll Number : 101

In the above example, we have explicitly defined a default Student constructor and initialized the values of name and rollNumber. Now, in the program below, we will not define a default constructor.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    public static void main(String[] args) {
        Student student = new Student();
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);
    }
}
Student Name : null
Student Roll Number : 0

When we do not define a constructor in a class, the compiler automatically provides a default constructor. However, this default constructor does not initialize instance variables with custom values—instead, it assigns default values to them based on their data types.

Data typeDefault value
int0
double0.0
booleanfalse
char \u0000
String or any Object null

In the above example, since name (a String) is an object, its default value is null, and since age (an int) is a primitive type, its default value is 0.

Parameterized Constructor

A parameterized constructor takes arguments and allows object initialization with specific values.

Important points

1. It takes parameters to initialize an object with specific values.
2. Useful when different objects require different initial values.
3. Supports constructor overloading by defining multiple constructors with different parameter lists.

Syntax

class ClassName 
{
    // Parameterized Constructor

    ClassName(dataType param1, dataType param2, ...) 
    {
        // Initialization code using parameters
    }
}

Write a program to define a parameterized constructor.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    // Constructor
    public Student(String name, int rollNumber) {
        this.name = name;
        this.rollNumber = rollNumber;
    }

    public static void main(String[] args) {
        Student student = new Student("Shweta", 102);
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);
    }
}
Output:
Student Name : Shweta
Student Roll Number : 102

In the above example, we have passed name and rollNumber as parameters in the Student Constructor.

Copy Constructor (User-Defined Constructor in Java)

Java does not provide a built-in copy constructor like C++, but it can be implemented manually to create a new object by copying another object’s values.

Important points

1. Used to create a duplicate object by copying values from an existing object.
2. Helps in avoiding direct object reference issues.

Syntax

class ClassName 
{
    // Parameterized Constructor

    ClassName(ClassName obj) 
    {
        // Copy values from obj
    }
}

Write a program to understand the copy constructor.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    // Constructor
    public Student(String name, int rollNumber) {
        this.name = name;
        this.rollNumber = rollNumber;
    }

    // Copy constructor
    public Student(Student student) {
        this.name = student.name;
        this.rollNumber = student.rollNumber;
    }

    public static void main(String[] args) {
        Student student = new Student("Shweta", 102);
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);

        Student copyStudent = new Student(student);
        System.out.println("Copy Student Name : "+ copyStudent.name);
        System.out.println("Copy Student Roll Number : "+copyStudent.rollNumber);

    }
}
Output:
Student Name : Shweta
Student Roll Number : 102
Copy Student Name : Shweta
Copy Student Roll Number : 102

In the above example, we have used a copy constructor to initialize a new Student object by copying the values of instance variables from an existing Student object.

Constructor Overloading

Constructor overloading in Java allows a class to have multiple constructors with the same name but different parameter lists. This enables object initialization in different ways based on the provided arguments.

Key Rules for Constructor Overloading

1. Constructors must have the same name as the class.
2. They must have different parameter lists (number, type, or order of parameters).
3. The Java compiler differentiates constructors based on their signatures.

Write a program to understand the constructor overloading.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    public Student(String name) {
        this.name = name;
    }

    // Constructor
    public Student(String name, int rollNumber) {
        this.name = name;
        this.rollNumber = rollNumber;
    }


    public static void main(String[] args) {
        Student student1 = new Student("Suraj");
        System.out.println("Student1 Name : "+ student1.name);
        System.out.println("Student1 Roll Number : "+student1.rollNumber);

        Student student2 = new Student("Shweta", 102);
        System.out.println("Student2 Name : "+ student2.name);
        System.out.println("Student2 Roll Number : "+student2.rollNumber);
    }
}
Output:
Student1 Name : Suraj
Student1 Roll Number : 0
Student2 Name : Shweta
Student2 Roll Number : 102

In the above example, we have 2 constructors. One constructor takes only the name as an argument, whereas the other takes the name and rollNumber as arguments.

Rules of Constructors

1. Same Name as the Class – A constructor must have the same name as the class.

class Student 
{
    Student()         // Constructor name matches class name
    {
        System.out.println("Constructor called");
    }
}

2. No Return Type – Constructors do not have a return type, not even void. If a return type is specified, it will be treated as a normal method, not a constructor.

class Student 
{
    void Student()       // This is NOT a constructor; it's a method
    {
        System.out.println("This is a method, not a constructor");
    }
}

3. Automatically Invoked – A constructor is automatically called when an object is created.

class Student 
{
    Student() 
    {
        System.out.println("Constructor invoked");
    }

    public static void main(String[] args) 
    {
        Student s = new Student(); // Constructor is automatically called
    }
}
Output: Constructor invoked

4. Can Be Overloaded but Not Overridden – A class can have multiple constructors with different parameter lists (constructor overloading), but they cannot be overridden because they are not inherited.

class Student 
{
    Student() 
    {
        System.out.println("Default constructor");
    }

    Student(String name) 
    {
        System.out.println("Parameterized constructor: " + name);
    }
}

5. Cannot be static, final, or abstract

static: Constructors belong to objects, not classes, so they cannot be static.
final: Constructors cannot be inherited or overridden, so final is unnecessary.
abstract: Abstract classes cannot be instantiated, so an abstract constructor makes no sense.

class Student 
{
    static Student() {}      // Error
    final Student() {}        // Error
    abstract Student() {}  // Error
}

Characteristics of Constructors

1. Used for Object Initialization – Constructors initialize instance variables when an object is created.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    // Constructor
    public Student(String name, int rollNumber) {
        this.name = name;
        this.rollNumber = rollNumber;
    }

    public static void main(String[] args) {
        Student student = new Student("Shweta", 102);
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);
    }
}
Output: 
Student Name : Shweta
Student Roll Number : 102

2. Constructor chaining – It is a technique in Java where one constructor calls another constructor within the same class or a parent class. It helps in reusing initialization logic and avoiding code duplication.

Supports this() and super() call.

this() – Calls another constructor of the same class.

super() – Calls the parent class constructor. If a class extends another class, the parent constructor (super()) is called implicitly if not specified.

Write a program to understand the this keyword with reference to the constructor.

package com.java.handson.constructors;

public class Student {

    private String name;
    private int rollNumber;

    Student(String name) {
        this.name = name;
    }

    // Constructor
    public Student(String name, int rollNumber) {
        this(name);
        this.rollNumber = rollNumber;
    }

    public static void main(String[] args) {
        Student student = new Student("Suraj", 101);
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);
    }
}
Output:
Student Name : Suraj
Student Roll Number : 101

The above example demonstrates constructor chaining using #this(name) to call another constructor from within the same class. The first constructor initializes only the name, while the second initializes both the name and rollNumber. When an object is created using the second constructor, both instance variables are properly initialized and printed.

Write a program to understand the super keyword with reference to the constructor.

package com.java.handson.constructors;

class Person {
    String name;

    Person(String name) {
        this.name = name;
    }
}

public class Student extends Person {
    private int rollNumber;
    // Constructor
    public Student(String name, int rollNumber) {
        super(name);
        this.rollNumber = rollNumber;
    }

    public static void main(String[] args) {
        Student student = new Student("Suraj", 101);
        System.out.println("Student Name : "+ student.name);
        System.out.println("Student Roll Number : "+student.rollNumber);
    }
}
Output:
Student Name : Suraj
Student Roll Number : 101

This example demonstrates constructor chaining across inheritance using #super(name) to call the parent class Person constructor. The Person constructor initializes the name, while the Student constructor sets the rollNumber. When a Student object is created, both parent and child class fields are initialized and printed.

3. A constructor can be Private (Singleton design pattern) – A constructor can be private, restricting object creation outside the class.

class Student {
    private static Student instance;
    private Student() {} // Private constructor

    public static Student getInstance() {
        if (instance == null) {
            instance = new Student();
        }
        return instance;
    }
}

This class implements the Singleton Design Pattern using a private constructor to restrict object creation. The #getInstance() method ensures only one instance of Student is created during the application’s lifecycle. This approach provides controlled access to the single instance, ensuring memory efficiency and consistency.

Static Block vs Constructor

Static Block

1. Initializes static variables and performs class-level setup.
2. Executes once, when the class is loaded into memory.
3. Defined using static {}.
4. Called only once, before the #main method runs.
5. It does not support parameters.
6. It cannot use this or super keyword because no object exists when the static block runs.

Constructor

1. Initializes instance variables when an object is created.
2. Executes every time an object is created.
3. Defined with the same name as the class and no return type.
4. Called every time a new object is created.
5. It supports parameters.
6. It can use this or the super keyword because an object is being created.

Write a program to understand the static block and the constructor.

package com.java.handson.constructors;

public class Student {

    private static int staticBlockCounter;
    private static int constructorBlockCounter;

    private String name;
    private int rollNumber;

    static {
        staticBlockCounter++;
    }
    // Constructor
    public Student(String name, int rollNumber) {
        constructorBlockCounter++;
        this.name = name;
        this.rollNumber = rollNumber;
    }

    public static void main(String[] args) {
        Student student1 = new Student("Suraj", 101);
        System.out.println("Student1 Name : "+ student1.name);
        System.out.println("Student1 Roll Number : "+student1.rollNumber);

        System.out.println("No.of students staticBlockCounter : "+staticBlockCounter);
        System.out.println("No.of students constructorBlockCounter : "+constructorBlockCounter);

        System.out.println();

        Student student2 = new Student("Shweta", 102);
        System.out.println("Student2 Name : "+ student2.name);
        System.out.println("Student2 Roll Number : "+student2.rollNumber);

        System.out.println("No.of students staticBlockCounter: "+staticBlockCounter);
        System.out.println("No.of students constructorBlockCounter : "+constructorBlockCounter);

    }
}
Output:
Student1 Name : Suraj
Student1 Roll Number : 101
No.of students staticBlockCounter : 1
No.of students constructorBlockCounter : 1

Student2 Name : Shweta
Student2 Roll Number : 102
No.of students staticBlockCounter: 1
No.of students constructorBlockCounter : 2

The static block is executed only once when the class is loaded; that is why we can see that staticBlockCounter is incremented only once, whereas the constructorBlockCounter is incremented twice, as there are 2 student objects, so the constructor is called twice.

Conclusion

Constructors are crucial for object initialization in Java, ensuring efficient and structured code. Understanding their types, overloading, and key rules helps in writing flexible and maintainable programs. Additionally, distinguishing constructors from static blocks clarifies their specific roles. Constructors handle instance initialization, while static blocks manage class-level setup. Mastering these concepts leads to better-designed and more scalable applications.

So this is all about constructors in Java. If you have any questions on this topic, please raise them in the comments section. If you liked this article, then please share this post with your friends and colleagues.

Leave a Comment