How to Call One Constructor from Another in Java: Non-Obvious Details That Will Change Your Code
Have you ever written a Java class with 5–6 constructors and felt like you were drowning in code duplication? Or, on the contrary, have you looked at someone else's code where the mysterious this(name, 0, true) appears and wondered: "What kind of magic is this?"
The question "How do I call one constructor from another in Java?" is one of the most popular on Stack Overflow (thousands of views and hundreds of answers). And for good reason. Seemingly a simple operation — calling a constructor — hides many nuances that affect performance, readability, and even the correctness of the program.
In this article, we will not just show the syntax. We will look under the hood of the JVM, analyze how the compiler handles such calls, and provide practical tips useful for both beginners and experienced developers.
Why Call a Constructor from a Constructor? The Duplication Problem
Imagine you are writing a User class that has mandatory fields (name, email) and optional ones (age, phone). You want to give your API users flexibility: create an object with a minimal set of data or with all the details.
Bad approach (without calling a constructor):
public class User { private String name; private String email; private int age; private String phone;
public User(String name, String email) { this.name = name; this.email = email; this.age = 0; // default value this.phone = null; // default value }
public User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; this.phone = null; // duplication again }
public User(String name, String email, int age, String phone) { this.name = name; this.email = email; this.age = age; this.phone = phone; }}Here we assign name and email three times. Adding a new field would require editing all constructors. This violates the DRY principle (Don't Repeat Yourself) and increases the risk of errors.
Good approach (with constructor call via this()):
public class User { private String name; private String email; private int age; private String phone;
public User(String name, String email) { this(name, email, 0, null); // delegate to the "fullest" constructor }
public User(String name, String email, int age) { this(name, email, age, null); // delegation again }
public User(String name, String email, int age, String phone) { this.name = name; this.email = email; this.age = age; this.phone = phone; }}Now all initialization logic is in one constructor. The rest simply delegate work to it, passing default values. This is concise, easy to maintain, and reduces the chance of forgetting a field.
Constructor Call Syntax: this() and super()
In Java, there are two keywords for calling constructors:
this(parameters)— calls another constructor of the same class.super(parameters)— calls a constructor of the parent class.
Critical rule: The call to this() or super() must be the first statement in the constructor. Why? More on that later.
Example with inheritance:
class Animal { private String species;
public Animal(String species) { this.species = species; System.out.println("Animal constructor: " + species);