Skip to content

Latest commit

 

History

History
1919 lines (1278 loc) · 27.5 KB

File metadata and controls

1919 lines (1278 loc) · 27.5 KB

Constructor in Java — DEEP DIVE 🔥

Let's build the concept from zero → object creation → constructor execution → this → shadowing → constructor types → overloading → common traps.


1. First: What Problem Does a Constructor Solve?

Suppose we create a Student object:

Student s = new Student();

The object exists, but how do we give it meaningful initial values?

Without a constructor:

class Student {
    int id;
    String name;

    public static void main(String[] args) {

        Student s = new Student();

        s.id = 101;
        s.name = "Ravi";

        System.out.println(s.id + " " + s.name);
    }
}

We have to:

  1. Create the object.
  2. Access the fields.
  3. Assign values separately.

A constructor allows initialization to happen as part of object creation.

class Student {

    int id;
    String name;

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static void main(String[] args) {

        Student s = new Student(101, "Ravi");

        System.out.println(s.id + " " + s.name);
    }
}

Output:

101 Ravi

The important idea is:

new Student(101, "Ravi")
          ↓
    Constructor
          ↓
   Object initialized

2. What Exactly Is a Constructor?

A constructor is a special member of a class that is invoked when an object is initialized through class-instance creation.

A constructor:

  • has the same name as the class
  • has no return type
  • can accept parameters
  • can be overloaded
  • is invoked automatically as part of new
  • is primarily used to initialize object state

Example:

class Student {

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

Creating an object:

Student s = new Student();

Output:

Constructor executed

You did not explicitly write:

s.Student();

The constructor is invoked as part of:

new Student();

3. Constructor vs Method

This is one of the most common doubts.

Compare:

class Student {

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

    void Student() {
        System.out.println("Method");
    }
}

The first is a constructor:

Student()

The second is a method:

void Student()

Why?

Because the second has:

void

A constructor cannot have a return type, not even void.

Comparison

Constructor Method
Same name as class Can have any valid name
No return type Has return type or void
Invoked during object creation Invoked explicitly or through method calls
Used mainly for initialization Used to perform operations
Can be overloaded Can be overloaded
Not inherited Methods can be inherited depending on circumstances

4. The new Expression — Very Important

Consider:

Student s = new Student(101, "Ravi");

Don't treat this as one mysterious statement.

Break it down:

Student
  ↓
reference type

s
  ↓
reference variable

new
  ↓
creates a new object

Student(101, "Ravi")
  ↓
constructor invocation

Conceptually:

Student s
   ↓
reference variable declared

new Student(...)
   ↓
new object initialized

=
   ↓
reference stored in s

5. What Happens During Object Creation?

For:

Student s = new Student(101, "Ravi");

a simplified conceptual flow is:

1. Class information is available
        ↓
2. Memory is allocated for the object
        ↓
3. Instance fields initially receive default values
        ↓
4. Constructor invocation begins
        ↓
5. Constructor body initializes state
        ↓
6. Reference to the object is assigned to s

For example:

class Student {

    int id;
    String name;

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Before constructor assignments, conceptually:

id   = 0
name = null

Then:

this.id = id
this.name = name

After construction:

id   = 101
name = "Ravi"

6. Instance Variables

Consider:

class Student {

    int id;
    String name;
}

These are instance variables.

They belong to each object.

Suppose:

Student s1 = new Student();
Student s2 = new Student();

Conceptually:

s1 object                 s2 object
┌──────────────┐          ┌──────────────┐
│ id = ...     │          │ id = ...     │
│ name = ...   │          │ name = ...   │
└──────────────┘          └──────────────┘

Each object has its own instance state.


7. Local Variables

Now:

void display() {

    int marks = 90;
}

marks is a local variable.

It belongs to the execution of display(), not to each object as a field.


8. Instance vs Local Variables

Feature Instance Variable Local Variable
Declared Inside class, outside methods/constructors Inside method/constructor/block
Belongs to Object Method/block execution
Default value Yes No
Must be definitely assigned before reading No Yes
Scope Instance context Declaring method/block
Example int id; int x = 10;

Example:

class Student {

    int id;                  // instance variable

    Student(int value) {

        int x = 10;          // local variable

        id = value;
    }
}

9. Why Do Instance Variables Get Default Values?

Suppose:

class Demo {

    int x;
    double price;
    boolean flag;
    String name;
}

If an object is created:

Demo d = new Demo();

The fields receive their default values:

int      → 0
double   → 0.0
boolean  → false
reference → null

But local variables are different:

int x;
System.out.println(x);

❌ Compile-time error because x has not been definitely assigned.


10. Non-Parameterized / No-Argument Constructor

A constructor with zero parameters:

class Student {

    Student() {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        Student s = new Student();
    }
}

Output:

Hello

More precise terminology:

No-argument constructor means a constructor whose parameter list is empty.

Some textbooks call it a non-parameterized constructor.


11. Parameterized Constructor

A constructor that accepts parameters:

class Student {

    int id;
    String name;

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static void main(String[] args) {

        Student s = new Student(101, "Ravi");

        System.out.println(s.id);
        System.out.println(s.name);
    }
}

Output:

101
Ravi

Here:

Student(int id, String name)

is a parameterized constructor.


12. The Shadowing Problem

Now we reach a very important concept.

Suppose:

class Student {

    int id;

    Student(int id) {
        id = id;
    }
}

At first glance, it looks like:

instance id = parameter id

But that's not what happens.

The constructor parameter:

int id

has the same name as the instance field:

int id

The parameter shadows the instance variable within the constructor's scope.

Therefore:

id = id;

effectively refers to the parameter on both sides.

The instance field remains unchanged.


13. Demonstrating Shadowing

class Student {

    int id;
    String name;

    Student(int id, String name) {

        id = id;
        name = name;
    }

    public static void main(String[] args) {

        Student s = new Student(101, "Ravi");

        System.out.println(s.id + " " + s.name);
    }
}

Output:

0 null

Why?

Because:

id = id;

doesn't mean:

object.id = parameter.id

Instead, the local parameter shadows the field.


14. The Solution: this

this is a reference that represents the current object.

So:

this.id

means:

The id field belonging to the current object.

Therefore:

this.id = id;

means:

current object's id = constructor parameter id

Similarly:

this.name = name;

means:

current object's name = constructor parameter name

15. Correct Constructor

class Student {

    int id;
    String name;

    Student(int id, String name) {

        this.id = id;
        this.name = name;
    }

    public static void main(String[] args) {

        Student s = new Student(101, "Ravi");

        System.out.println(s.id + " " + s.name);
    }
}

Output:

101 Ravi

Remember this pattern:

this.field = parameter;

This is extremely common in Java constructors.


16. What Exactly Is this?

Suppose:

Student s1 = new Student(101, "Ravi");

Inside the constructor, this refers to the object currently being initialized.

Conceptually:

new Student(...)
       ↓
   current object
       ↑
      this

For another object:

Student s2 = new Student(102, "Priya");

during that constructor invocation, this refers to the second object.

So this is not a fixed object.

It refers to the current object for that invocation.


17. Can We Use this Without Shadowing?

Yes.

For example:

class Student {

    int id;

    Student(int value) {
        this.id = value;
    }
}

There is no shadowing because the parameter is named value.

Here, this is also valid:

id = value;

So this isn't required merely because you're inside a constructor.

It's particularly useful when the parameter and field have the same name.


18. Constructor Overloading

Just like methods, constructors can be overloaded.

class Student {

    int id;
    String name;

    Student() {
        id = 0;
        name = "Unknown";
    }

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Now there are two constructors:

Student()
Student(int, String)

Java selects the appropriate constructor based on the arguments supplied to new.

new Student();

calls:

Student()

while:

new Student(101, "Ravi");

calls:

Student(int, String)

19. Constructor Overloading vs Method Overloading

Constructor overloading

Student()
Student(int id)
Student(int id, String name)

Same class name + different parameter lists.

Method overloading

display()
display(int x)
display(int x, int y)

Same method name + different parameter lists.

The principle is similar.


20. Can Constructor Return a Value?

❌ No.

This is invalid:

class Student {

    int Student() {
        return 10;
    }
}

This is not a constructor.

It is a method named Student, because:

int

is present.

Correct constructor:

Student() {
}

21. Can Constructor Be void?

❌ No.

This:

void Student() {
}

is a method, not a constructor.

Remember:

Student()       → constructor
void Student()  → method

22. Can Constructor Be static?

❌ No.

Constructors are associated with object initialization, so Java does not allow:

static Student() {
}

23. Can Constructor Be final?

❌ No.

Constructors cannot be declared final.


24. Can Constructor Be abstract?

❌ No.

An abstract method has no implementation and requires overriding.

A constructor is used for object initialization and isn't inherited/overridden.


25. Can Constructor Be private?

✅ Yes.

Example:

class Demo {

    private Demo() {
        System.out.println("Private constructor");
    }
}

A private constructor prevents normal object creation from outside the class:

Demo d = new Demo();  // ❌ outside the class

Private constructors are useful in patterns such as controlled instantiation and utility-style classes.


26. Can Constructor Be public?

Yes.

public Student() {
}

Its accessibility depends on the access modifier.

Possible access levels include:

public
protected
package-private (no modifier)
private

27. What If We Don't Write Any Constructor?

Consider:

class Student {

    int id;
    String name;
}

There is no constructor written.

Java can provide a default constructor automatically.

Conceptually:

Student() {
    super();
}

The exact source code isn't literally inserted into your file, but this is a useful conceptual model.

Then:

Student s = new Student();

works.


28. Huge Trap: Default Constructor vs No-Argument Constructor

These terms are often mixed up.

No-argument constructor

Any constructor with zero parameters:

Student() {
}

It may be written by you.

Default constructor

The constructor the compiler provides if you don't declare any constructor.

So:

class Student {
}

gets a compiler-provided no-argument constructor.

But:

class Student {

    Student() {
    }
}

has a programmer-written no-argument constructor.


29. What Happens If We Write a Parameterized Constructor?

Consider:

class Student {

    Student(int id) {
    }
}

Now:

Student s = new Student();

❌ Compile-time error.

Why?

Because once you declare a constructor yourself, the compiler does not additionally provide the default no-argument constructor.

You must explicitly provide one if you want it:

Student() {
}

So:

class Student {

    Student() {
    }

    Student(int id) {
    }
}

Now both are available.


30. Constructor Chaining with this()

this() is different from this.

this

Refers to the current object:

this.id = id;

this()

Calls another constructor in the same class.

Example:

class Student {

    int id;
    String name;

    Student() {
        this(0, "Unknown");
    }

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Now:

Student s = new Student();

Flow:

Student()
   ↓
this(0, "Unknown")
   ↓
Student(int, String)
   ↓
fields initialized

This is called constructor chaining.


31. Rule for this()

If used inside a constructor:

this(...);

must be the first statement in that constructor.

Correct:

Student() {
    this(0, "Unknown");
}

Incorrect:

Student() {
    System.out.println("Hello");
    this(0, "Unknown");  // ❌
}

32. this() vs this

Memorize this difference:

this this()
Refers to current object Calls another constructor in same class
Used like this.id Used like this(...)
Can access instance members Must be first statement when used in constructor
Doesn't invoke a constructor Invokes another constructor

33. Constructor Chaining with super()

There is another important keyword:

super()

It invokes a constructor of the superclass.

Example:

class Animal {

    Animal() {
        System.out.println("Animal constructor");
    }
}

class Dog extends Animal {

    Dog() {
        super();
        System.out.println("Dog constructor");
    }
}

Creating:

Dog d = new Dog();

Output:

Animal constructor
Dog constructor

Why?

The superclass part of the object must be initialized as part of construction.


34. this() vs super()

this()
 ↓
constructor of same class

super()
 ↓
constructor of superclass

Both, when explicitly used in a constructor, must appear as the first statement.

Therefore you cannot write:

this();
super();

in the same constructor.

You must choose the constructor invocation that applies.


35. Constructor and Inheritance

Are constructors inherited?

❌ No.

Suppose:

class Animal {
    Animal() {
    }
}

class Dog extends Animal {
}

Dog does not inherit Animal() as a constructor.

But when a Dog object is constructed, a superclass constructor is invoked as part of construction.

This distinction is important:

Constructor inherited? → No
Superclass constructor invoked? → Yes

36. Can a Constructor Be Overridden?

❌ No.

Overriding applies to inherited methods.

Constructors aren't inherited, so they cannot be overridden.


37. Can a Constructor Be Overloaded?

✅ Yes.

Example:

Student()
Student(int id)
Student(int id, String name)

38. Can a Constructor Call a Method?

Yes.

class Student {

    Student() {
        display();
    }

    void display() {
        System.out.println("Hello");
    }
}

However, calling overridable instance methods from constructors can be dangerous in inheritance scenarios because subclass state may not yet be initialized. That's an advanced design concern worth remembering.


39. Can a Constructor Call Another Constructor?

Yes.

Using:

this(...)

Example:

class Student {

    Student() {
        this(101);
    }

    Student(int id) {
        System.out.println(id);
    }
}

40. Can We Explicitly Call a Constructor Like a Method?

❌ No.

This is invalid:

s.Student();

Constructors are invoked through object creation expressions such as:

new Student();

or through constructor chaining:

this();
super();

41. One-Line Object Creation Without Local Variable

You can write:

System.out.println(new Student(101, "Ravi").id);

Here you don't declare:

Student s;

The object is created and its field is accessed immediately.

This is useful for simple cases, but if you need the object multiple times, a reference variable is clearer:

Student s = new Student(101, "Ravi");

42. "Print Output in One Line Using Constructor"

Suppose your goal is:

101 Ravi

You can initialize through a constructor:

class Student {

    int id;
    String name;

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static void main(String[] args) {

        Student s = new Student(101, "Ravi");

        System.out.println(s.id + " " + s.name);
    }
}

The constructor initializes.

The println() prints.

Don't say the constructor itself is printing the object's fields unless the constructor contains the println().


43. Constructor That Prints Directly

You can also write:

class Student {

    Student(int id, String name) {
        System.out.println(id + " " + name);
    }

    public static void main(String[] args) {
        new Student(101, "Ravi");
    }
}

Output:

101 Ravi

Here the constructor itself performs the printing.

But this is conceptually different from:

Student s = new Student(101, "Ravi");
System.out.println(s.id + " " + s.name);

The latter uses the constructor for initialization, which is generally the more important use.


44. Constructor Is Not Required to Initialize Every Field

Example:

class Student {

    int id;
    String name;
    int age;

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

age isn't explicitly initialized by the constructor.

It still receives its default value:

age = 0

45. Constructor Can Validate Input

Constructors can do more than simple assignment.

class Student {

    int age;

    Student(int age) {

        if (age >= 0) {
            this.age = age;
        } else {
            this.age = 0;
        }
    }
}

Now object creation and initial validation happen together.


46. Constructor Can Initialize Multiple Fields

class Employee {

    int id;
    String name;
    double salary;

    Employee(int id, String name, double salary) {

        this.id = id;
        this.name = name;
        this.salary = salary;
    }
}

One constructor initializes three pieces of state.


47. Multiple Objects, Different Constructor Values

class Student {

    int id;
    String name;

    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static void main(String[] args) {

        Student s1 = new Student(101, "Ravi");
        Student s2 = new Student(102, "Priya");

        System.out.println(s1.id + " " + s1.name);
        System.out.println(s2.id + " " + s2.name);
    }
}

Output:

101 Ravi
102 Priya

Each constructor invocation initializes a different object.


48. Deep Understanding of Shadowing

Consider:

class Student {

    int id;

    Student(int id) {
        this.id = id;
    }
}

There are actually two different variables named id.

                    id
                   /  \
                  /    \
        instance field   parameter
             ↓               ↓
         this.id             id

So:

this.id = id;

means:

object field = parameter

This is why the statement is so common in Java.


49. Local Variable vs Parameter

A constructor parameter is a local variable of the constructor's invocation, but when teaching Java, it's useful to distinguish:

local variable
parameter
instance variable

Example:

class Student {

    int id;                   // instance variable

    Student(int value) {      // parameter

        int x = 10;           // local variable

        this.id = value;
    }
}

All three have different roles.


50. Complete Constructor Program

Here's a program bringing many concepts together:

class Student {

    // Instance variables
    int id;
    String name;
    int age;

    // No-argument constructor
    Student() {
        this(0, "Unknown", 0);
    }

    // Parameterized constructor
    Student(int id, String name, int age) {

        this.id = id;
        this.name = name;
        this.age = age;
    }

    void display() {
        System.out.println(id + " " + name + " " + age);
    }

    public static void main(String[] args) {

        Student s1 = new Student();

        Student s2 = new Student(101, "Ravi", 20);

        s1.display();
        s2.display();
    }
}

Output:

0 Unknown 0
101 Ravi 20

Notice the complete flow:

new Student()
      ↓
Student()
      ↓
this(0, "Unknown", 0)
      ↓
Student(int, String, int)
      ↓
this.id = id
this.name = name
this.age = age

51. Constructor Cheat Sheet

┌──────────────────────────────────────┐
│          CONSTRUCTOR                 │
├──────────────────────────────────────┤
│ Same name as class                  │
│ No return type                      │
│ Called during object creation       │
│ Used for initialization             │
│ Can have parameters                 │
│ Can be overloaded                   │
│ Not inherited                       │
│ Cannot be overridden                │
│ Can be private                      │
│ Cannot be static/final/abstract     │
└──────────────────────────────────────┘

52. The Most Important Constructor Distinctions

Constructor vs method

Constructor → no return type
Method      → return type/void

this vs this()

this.field
    ↓
current object's field

this(...)
    ↓
another constructor in same class

this() vs super()

this()
 ↓
same class constructor

super()
 ↓
superclass constructor

Default vs no-argument

Default constructor
→ compiler-provided when no constructor is declared

No-argument constructor
→ any constructor with zero parameters

Overloading vs overriding

Constructor → can overload
Constructor → cannot override

🧪 FINAL DOUBT CHECK

Q1. Is this a constructor?

Student() {
}

✅ Yes.


Q2. Is this a constructor?

void Student() {
}

❌ No. It's a method.


Q3. Is this a constructor?

int Student() {
    return 10;
}

❌ No. It's a method.


Q4. Can constructors be overloaded?

✅ Yes.


Q5. Can constructors be inherited?

❌ No.


Q6. Can constructors be overridden?

❌ No.


Q7. Can a constructor be private?

✅ Yes.


Q8. Can a constructor be static?

❌ No.


Q9. Can a constructor use this?

✅ Yes.

Example:

this.id = id;

Q10. Can a constructor call another constructor?

✅ Yes:

this(101);

Q11. Can this() and super() both be explicit statements in the same constructor?

❌ No. Each, when used, must be the first statement, so you cannot use both explicitly in the same constructor.


🏆 MASTER MEMORY

If you remember only this, you can reconstruct most of the topic:

                    CONSTRUCTOR
                         │
             Same name as the class
                         │
                    No return type
                         │
                Called during new
                         │
                  Initializes object
                         │
            ┌────────────┴────────────┐
            ↓                         ↓
       No-argument                Parameterized
            │                         │
       Student()              Student(int id,...)
                                      │
                                      ↓
                              this.id = id
                                      │
                                      ↓
                                avoids shadowing

⭐ Final golden statement

A constructor is a special class member with the same name as the class and no return type, invoked as part of object creation to initialize the object's state. Constructors may be overloaded, are not inherited or overridden, and this is commonly used to distinguish instance variables from constructor parameters when shadowing occurs.