What is constructor overloading in Java, and how does this() chaining work?
answer
- overload = same name, different parameter lists
- compiler picks by argument types (overload resolution)
- this(...) delegates within the same class
- this(...)/super(...) must be FIRST statement
- either this() or super(), not both; no cycles
basics
~20 sConstructor overloading means a class has several constructors with different parameter lists, so you can create objects in different ways. One constructor can call another in the same class using this(...) to avoid repeating setup code.
solid answer
~40 sConstructor overloading is declaring multiple constructors in one class that differ in their parameter lists (number, types, or order of parameters). It gives callers several ways to create an object — e.g. `new Rectangle(w, h)` vs `new Rectangle(size)` for a square. The compiler picks which one to run by matching the argument types at the call site, exactly like method overloading. To avoid duplicating initialization logic, one constructor can delegate to another in the same class with `this(args)`. The `this(...)` call must be the very first statement in the constructor, and you can't use both `this(...)` and `super(...)` in the same constructor. This chaining funnels every constructor through one 'primary' constructor that holds the real logic and validation, keeping things DRY and consistent.
code
java · 20 linesclass User {
private final String name;
private final int age;
// primary constructor: all logic + validation here
public User(String name, int age) {
if (age < 0) throw new IllegalArgumentException("age");
this.name = name;
this.age = age;
}
// overloaded, delegating constructor
public User(String name) {
this(name, 0); // must be the first statement
}
public User() {
this("anonymous"); // chains: User() -> User(String) -> User(String,int)
}
}go deeper
Knows a class can have several constructors with different parameters, and that you call new with matching arguments.
Explains overload resolution by signature and uses this(...) to delegate to a primary constructor as the first statement.
Centralizes validation in one primary constructor, knows the this/super first-statement and mutual-exclusion rules, and recognizes telescoping smell pointing toward a builder.
Weighs overloaded constructors vs. static factory methods vs. builders for API clarity and evolvability; sets conventions for invariant enforcement and parameter explosion.
## Overloading, generally **Overloading** means giving several methods (or constructors) the **same name** but **different parameter lists**. Java tells them apart by the **signature** — the number, types, and order of parameters. The return type is *not* part of the signature, and for constructors there's no return type anyway. ## Constructor overloading Since all constructors of a class share the class's name, overloading is how you provide **multiple ways to build** an object: ```java class Rectangle { int width, height; Rectangle(int width, int height) { this.width = width; this.height = height; } Rectangle(int size) { this.width = size; this.height = size; } // square Rectangle() { this.width = 1; this.height = 1; } // unit } ``` At each `new Rectangle(...)` call, the compiler performs **overload resolution**: it matches the argument types against the available constructor signatures and binds to the best fit. `new Rectangle(3, 4)` → first; `new Rectangle(5)` → second; `new Rectangle()` → third. If two are equally good (ambiguous), it's a compile error. ## Avoiding duplication with this(...) Notice the constructors repeat the field-assignment logic. To stay **DRY** (Don't Repeat Yourself), a constructor can **delegate** to another constructor in the *same* class using the `this(...)` call: ```java class Rectangle { int width, height; Rectangle(int width, int height) { // the 'primary' constructor this.width = width; this.height = height; } Rectangle(int size) { this(size, size); } // delegates Rectangle() { this(1, 1); } // delegates } ``` Now all initialization (and any validation) lives in **one** place; the others just forward arguments. ## Rules of this(...) and super(...) 1. A `this(...)` call must be the **first statement** in the constructor body (nothing may precede it). 2. Likewise `super(...)` must be first if used. 3. Because both must be first, a constructor can contain **either** `this(...)` **or** `super(...)` — never both. 4. The constructor you delegate to will itself, eventually, reach a constructor that calls `super(...)` — so the superclass is still constructed exactly once. 5. No cycles: `A()` calling `this(x)` which calls back `this()` would be a compile error (recursive constructor invocation). ## Why this matters Funneling every constructor through one primary constructor centralizes validation and invariant-enforcement, so you can't accidentally create a valid object through one path and an invalid one through another. It's the constructor counterpart of the telescoping-constructor pattern (and the reason builders exist when the parameter list grows large).
- Can return type or parameter names distinguish two constructors?No. Constructors have no return type, and parameter names are irrelevant — only the parameter types/count/order (the signature) distinguish overloads. Two constructors with the same types but different names of params won't compile.
- What happens if I put a statement before this(...)?Compile error. this(...) and super(...) must be the first statement. (Java 22+ relaxes this slightly, allowing some statements before super()/this() as a preview feature.)
Overloaded constructors are like several order forms for the same product (full form, short form, default). this(...) chaining is each short form quietly filling in the blanks and submitting the one master form, so the real processing happens in one office.
saying these in an interview costs you the question
- Thinking overloads can differ only by return type (constructors have none)
- Putting code before this(...) or super(...)
- Using both this(...) and super(...) in one constructor
- Creating a constructor delegation cycle (recursive this() calls)
- Believing parameter names (not types) distinguish overloads