🏗️ Classes & Objects · Intermediate

Constructors in Java

Same name as class, no return type, the implicit default constructor and when it disappears.

🧩 The mysteryYour code compiled yesterday. Today you added a constructor to a class — and a line you never touched stopped compiling. Java took something away from you. What?

The birth of an object

A constructor runs once per new to set up the fresh object. Two rules make it a constructor: it has exactly the class's name and **no return type — not even void**.

class Point {
    int x, y;
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
Point p = new Point(3, 4);

The free default constructor

Write no constructor at all and the compiler adds one for you: no parameters, the same access level as the class, and its only job is to call the parent's no-arg constructor, super(). But it's only free while you declare none.

🔮 Predict it

Spot the surprise

Tea has one constructor. What happens?

class Tea {
    String kind;
    Tea(String kind) { this.kind = kind; }
}
void main() {
    Tea t = new Tea();
    System.out.println(t.kind);
}
  1. null
  2. Compile error
  3. Throws NullPointerException
Show the answer

Compile error. Declaring Tea(String) means the compiler no longer adds the no-arg constructor, so new Tea() has nothing to match.

⚠️ The trap

void turns it into a method

Add void and your "constructor" becomes an ordinary method that just happens to be named Cat. The class is left with only the default constructor, so new Cat("Tom") fails to compile.

class Cat {
    String name;
    void Cat(String n) { // a method!
        name = n;
    }
}

Overloaded constructors

A class can have several constructors with different parameter lists. Each new picks the one whose parameters match the arguments.

class Lamp {
    Lamp() { ... }           // Lamp()
    Lamp(boolean on) { ... } // Lamp(true)
}
🔮 Predict it

Which one rings?

What does this print?

class Bell {
    Bell() { System.out.print("ding "); }
    Bell(int n) { System.out.print("dong "); }
}
void main() {
    new Bell(3);
    new Bell();
}
  1. ding dong
  2. dong ding
  3. dong dong
Show the answer

dong ding. new Bell(3) matches the int constructor, new Bell() the no-arg one. Same class, different setup paths.

💼 In the real world

In real projects

Frameworks like JPA/Hibernate and many JSON libraries create your objects through a no-arg constructor. Add a constructor with parameters, forget to keep a no-arg one, and they fail at runtime with errors like "No default constructor for entity".

Key takeaways

  1. Same name as the class, no return type
  2. Runs once per new, to initialize the object
  3. Default no-arg constructor exists only if you declare none
  4. Constructors can be overloaded with different parameters
🤯 Did you know?

Constructors aren't methods, even inside the JVM: they compile to a special method named <init> that no Java code can call by name.

Practice questions

What does this print?

class Point {
    int x;
    Point(int x) { this.x = x; }
}
void main() {
    Point p = new Point();
    System.out.println(p.x);
}
  1. 0
  2. Compile error
  3. null
  4. Throws NullPointerException
Check your answer

Compile error. Point declares a constructor, so the compiler no longer adds a no-argument one. new Point() has no matching constructor.

What does this print?

class Lamp {
    Lamp() { System.out.print("A"); }
    Lamp(boolean on) {
        System.out.print("B");
    }
}
void main() {
    new Lamp(); new Lamp(false); new Lamp();
}
  1. AAA
  2. ABA
  3. BAB
  4. AB
Check your answer

ABA. Constructors can be overloaded. Each new picks the constructor whose parameters match the arguments: no args runs A, a boolean runs B.

Next: balance = balance; compiles without a warning and does absolutely nothing. Meet this.