In this beginners-friendly guide, you will learn Java constructor overloading with examples. We will explain what constructor overloading is, why it is useful for students and new Java learners, how to write multiple constructors in one class, and the rules to avoid common mistakes. You will also see simple Java constructor examples, output, and a real-life use case. If you are just starting with Java, this page is part of our Java constructors tutorial under the CodDesire Java series. For more topics, visit our Java section.
- Overloading lets a class have multiple constructors that differ by parameter list (number, types, order).
- The compiler selects the matching constructor at compile time based on the arguments you pass.
- Prefer one validated “full” constructor and delegate from simpler ones using
this(...)for clean, centralized initialization.
What is constructor overloading in Java?
Constructor overloading in Java means a class can have more than one constructor, but each must have a different parameter list (number, types, and/or order of parameters). The compiler decides which constructor to call at compile time based on the arguments you pass.
In simple terms: it lets you create objects in different ways. For example, you might create a Box with no size, a Box with one size (a cube), or a Box with width, height, and depth.
Basic syntax reminder
- A constructor has the same name as the class.
- It has no return type (not even void).
- Constructors can be overloaded by changing their parameter lists.
Simple Java constructor examples (Box)
class Box {
int width, height, depth;
// Default (no-arg) constructor
Box() {
this(1, 1, 1); // delegate to the 3-arg constructor
}
// One-parameter (cube) constructor
Box(int size) {
this(size, size, size);
}
// Parameterized constructor
Box(int width, int height, int depth) {
this.width = width;
this.height = height;
this.depth = depth;
}
int volume() {
return width * height * depth;
}
class="cd-keyword cd-access">public static void main(String[] args) {
Box a = new Box(); // 1x1x1
Box b = new Box(5); // 5x5x5
Box c = new Box(2, 3, 4); // 2x3x4
System.out.println(a.volume());
System.out.println(b.volume());
System.out.println(c.volume());
}
}1
125
24Why use constructor overloading?
- Convenience for callers: Create objects with different sets of available information (e.g., with or without optional data).
- Readability: Code is easier to understand at the call site.
- Validation in one place: Use a “full” constructor for checks and delegate from simpler constructors.
- Backward compatibility: Add new ways to construct without breaking old code.
Default and parameterized constructors in Java
By default, if you do not write any constructor in a class, Java provides a compiler-generated no-argument constructor that simply calls the superclass constructor. But if you declare any constructor yourself, the default one is not generated.
| Type | When it exists | What it does |
|---|---|---|
| Default (no-arg) | Only if you declare no constructors at all | Initializes fields to default values (0, false, null), calls super() |
| Parameterized | Whenever you write it | Initializes fields using the provided arguments; often does validation |
How to overload a constructor in Java step by step
- Decide which sets of data you want to allow for object creation (e.g., name only, name + age).
- Create a full constructor that takes all required fields and does validation.
- Write simpler constructors that call the full one using
this(...)and pass default values as needed. - Test each constructor by creating objects and printing results.
this(...)Java constructor overloading example program for students (Student)
class Student {
String name;
int age;
String grade;
// 1) No-arg: default values
Student() {
this("Unknown", 0, "NA");
}
// 2) One-arg: name only
Student(String name) {
this(name, 0, "NA");
}
// 3) Two-arg: name + age
Student(String name, int age) {
this(name, age, "NA");
}
// 4) Three-arg: full constructor (centralized initialization)
Student(String name, int age, String grade) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Name must not be blank");
}
if (age < 0) {
throw new IllegalArgumentException("Age must be non-negative");
}
this.name = name;
this.age = age;
this.grade = grade;
}
void print() {
System.out.println(name + " (" + age + ") - " + grade);
}
class="cd-keyword cd-access">public static void main(String[] args) {
new Student().print();
new Student("Ava").print();
new Student("Ben", 19).print();
new Student("Chin", 20, "A").print();
}
}Unknown (0) - NA
Ava (0) - NA
Ben (19) - NA
Chin (20) - AConstructor chaining: this(…), super(…), and Java 25+ flexible bodies
Constructors can call other constructors:
this(...)calls another constructor in the same class (commonly used to delegate to the “full” constructor).super(...)calls a constructor in the superclass.
In Java 25 and later, the language allows certain statements to appear before this(...) or super(...). This is known as “flexible constructor bodies” and is useful for safe pre-validation or computing values before you delegate. You still cannot use the not-yet-initialized this (for example, calling an instance method) in that prologue.
| Aspect | this(…) | super(…) |
|---|---|---|
| Purpose | Delegate to another constructor in the same class (common for overloads) | Invoke a specific constructor in the superclass |
| Position in constructor | Traditionally first; Java 25+ allows limited statements before it | Traditionally first; Java 25+ allows limited statements before it |
| When required | Optional; use to centralize initialization | Implicit no-arg super() is inserted if none specified and available |
| Common mistake | Calling instance methods or using fields before delegation in Java 25+ prologue | Forgetting to call a non-existent no-arg super when superclass has no no-arg constructor |
| Example | this(name, age, "NA"); |
super(len); |
Example: pre-validation before calling super (Java 25+)
class Base {
Base(int x) {
System.out.println("Base with x = " + x);
}
}
class Sub extends Base {
Sub(String text) {
// Java 25+: allowed before super(...)
int len = (text == null) ? 0 : text.trim().length();
super(len);
}
class="cd-keyword cd-access">public static void main(String[] args) {
new Sub(" hello ");
}
}Base with x = 7If you are using Java versions before 25, put super(...) or this(...) as the very first statement in the constructor.
Constructor overloading rules in Java
- Constructors are distinguished only by their parameter lists (number, types, order). Return type does not apply to constructors.
- Throws clauses and generic type parameters do not differentiate overloads.
- Overload resolution follows the same compile-time rules as method overloading: the most specific applicable constructor is chosen; ambiguity is a compile-time error.
- Varargs (
...) is considered after fixed-arity matches. - Constructors are not inherited and cannot be overridden.
- If you write any constructor, Java will not generate a default no-arg constructor for you.
Ambiguity example
class Printer {
Printer(String s) { System.out.println("String"); }
Printer(StringBuilder sb) { System.out.println("StringBuilder"); }
class="cd-keyword cd-access">public static void main(String[] args) {
// new Printer(null); // Compile-time error: reference to Printer is ambiguous
new Printer("hi"); // OK - calls Printer(String)
new Printer(new StringBuilder("x")); // OK - calls Printer(StringBuilder)
}
}Varargs vs fixed-arity selection
class Reporter {
Reporter(String tag) {
System.out.println("Fixed-arity: one String");
}
Reporter(String... tags) {
System.out.println("Varargs: many Strings");
}
class="cd-keyword cd-access">public static void main(String[] args) {
new Reporter("debug"); // chooses the fixed-arity constructor
new Reporter("a", "b"); // chooses the varargs constructor
}
}Fixed-arity: one String
Varargs: many StringsConstructor overloading in Java with real life example
Imagine opening a bank account with minimum information at first, but also allowing a richer constructor later.
class BankAccount {
String owner;
double balance;
String type;
// Minimal: owner only
BankAccount(String owner) {
this(owner, 0.0, "SAVINGS");
}
// Owner + initial deposit
BankAccount(String owner, double initialDeposit) {
this(owner, initialDeposit, "SAVINGS");
}
// Full constructor with validation
BankAccount(String owner, double initialDeposit, String type) {
if (owner == null || owner.isBlank()) {
throw new IllegalArgumentException("Owner is required");
}
if (initialDeposit < 0) {
throw new IllegalArgumentException("Initial deposit must be non-negative");
}
this.owner = owner;
this.balance = initialDeposit;
this.type = type;
}
void print() {
System.out.println(owner + " | " + type + " | " + balance);
}
class="cd-keyword cd-access">public static void main(String[] args) {
new BankAccount("Riya").print();
new BankAccount("Sam", 1000).print();
new BankAccount("Lee", 500, "CURRENT").print();
}
}Riya | SAVINGS | 0.0
Sam | SAVINGS | 1000.0
Lee | CURRENT | 500.0Records and constructors (modern Java)
Java records provide a canonical constructor that matches their components, and you can write a compact constructor for validation. Any extra constructors must delegate to the canonical one using this(...).
record Point(int x, int y) {
// Compact canonical constructor: validate inputs
class="cd-keyword cd-access">public Point {
if (x < 0 || y < 0) {
throw new IllegalArgumentException("Coordinates must be non-negative");
}
}
// Additional overloaded constructor
class="cd-keyword cd-access">public Point(int both) {
this(both, both); // must delegate to the canonical constructor
}
}Common mistakes when overloading constructors in Java
- Thinking a default no-arg constructor always exists. It exists only if you did not write any constructor.
- Changing only the throws clause or generic type parameters—these do not create a new overload.
- Assuming return type matters—constructors have no return type.
- Calling instance methods or using
thisin the pre-delegation prologue (Java 25+ restriction). Perform only safe computations there. - Creating too many overloads (telescoping). Consider a builder or static factory for many optional fields.
- Ignoring ambiguity with
nullfor unrelated reference types (e.g.,StringvsStringBuilder).
FAQ: Beginners guide to Java constructors and overloading
What is constructor overloading in Java in simple terms?
It means writing multiple constructors in the same class with different parameter lists so you can create objects in different ways. The compiler picks the right one based on the arguments.
Why do we use constructor overloading in Java?
To provide flexible ways to create an object: minimal info, partial info, or full info with validation. It makes code cleaner and easier to use.
How do I write multiple constructors in one Java class?
Create a “full” constructor that initializes all required fields and performs checks. Then add simpler constructors that call it using this(...), supplying defaults for missing values. Test each path by creating objects with different arguments.
Is constructor overloading the same as method overloading in Java?
They follow similar selection rules, but constructors are special: they have no return type, are not inherited, and cannot be overridden. Overload resolution is done at compile time in both cases.
What happens if I don’t create any constructor in Java?
The compiler provides a default no-argument constructor that calls super(). If you declare any constructor yourself, Java does not add the default one.
Summary
Constructor overloading in Java for beginners is about giving your classes multiple, clear ways to be created. Start with one validated, full constructor and delegate from simpler ones with this(...). Understand the rules (parameter lists, overload resolution, varargs) and be aware of modern features like Java 25’s flexible constructor bodies. As you practice, try building small programs and then grow to real-life models like bank accounts or shapes. For more topics and practice, continue in our Java tutorials at CodDesire.
Sources / Further reading
- Java Language Specification, Constructor Declarations (incl. overloading): JLS SE 26
- Oracle Java Tutorials – Constructors: Providing Constructors for Your Classes
- Oracle Java Tutorials – Method Overloading (applies to resolution rules): Defining Methods
- JEP 513 – Flexible Constructor Bodies (Java 25): OpenJDK JEP 513
- Records overview (modern Java): Oracle Language Guide – Records


