An object without a constructor is a blank form — all the fields exist but nothing sensible fills them in. Constructors are how you guarantee an object starts life in a valid state, and they are where a surprising number of subtle bugs and interview questions live.
This tutorial covers the constructor types you actually use — default, parameterized, and copy — plus overloading and the this()/super() chaining that ties them together. If the idea of an object is still fuzzy, read classes and objects first.
What a constructor is
A constructor is a special block of code that runs automatically when you create an object with new. Two rules define one:
- Its name is exactly the class name.
- It has no return type — not even
void.
Those two rules are how the compiler tells a constructor apart from an ordinary method. If you accidentally add a return type, it silently becomes a regular method that never runs during construction — a classic bug.
class Book {
String title;
Book(String title) { // constructor: class name, no return type
this.title = title;
}
}
public class Main {
public static void main(String[] args) {
Book b = new Book("Effective Java");
System.out.println(b.title); // Effective Java
}
}
The new Book("Effective Java") call allocates the object and immediately runs the constructor, which sets title. The this.title = title line disambiguates the field from the parameter of the same name — this means "this object's field."
The default constructor and its disappearing act
If you write no constructor, Java quietly gives your class a no-argument constructor that does nothing but set fields to their defaults (0, false, null). That is the default constructor.
The trap: the moment you write any constructor, that free default vanishes.
class Account {
double balance;
Account(double balance) { // now the default no-arg constructor is gone
this.balance = balance;
}
}
public class Main {
public static void main(String[] args) {
// Account a = new Account(); // compile error: no such constructor
Account a = new Account(500); // this works
System.out.println(a.balance); // 500.0
}
}
Common mistake: Adding a parameterized constructor and then being surprised that
new Account()no longer compiles. Once you declare one constructor, you must explicitly write a no-arg constructor if you still want one. Frameworks like JPA and Jackson often require that no-arg constructor, so this bites people in real projects.
Parameterized constructors
A parameterized constructor takes arguments so callers can supply the initial state up front. This is the most common kind you will write, because it makes it impossible to create a half-initialized object.
class Rectangle {
int width;
int height;
Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
int area() {
return width * height;
}
}
public class Main {
public static void main(String[] args) {
Rectangle r = new Rectangle(4, 5);
System.out.println(r.area()); // 20
}
}
By forcing width and height at construction time, you guarantee no Rectangle ever exists without dimensions. That is the real value of a parameterized constructor — it enforces valid state, a core idea you will see again in encapsulation.
Constructor overloading
A class can have several constructors as long as their parameter lists differ. This is constructor overloading, and it lets callers build the object in whatever way suits them. It follows the same rules as method overloading — the compiler chooses based on the arguments you pass.
class Pizza {
String size;
boolean cheese;
Pizza() { // no-arg
this("medium", false); // delegates to the two-arg version
}
Pizza(String size) { // one-arg
this(size, false); // delegates too
}
Pizza(String size, boolean cheese) { // the "real" constructor
this.size = size;
this.cheese = cheese;
}
}
Notice this("medium", false) — that is one constructor calling another in the same class. This is constructor chaining with this(), and it keeps all the actual assignment logic in one place instead of duplicating it across three constructors.
Pro tip: Funnel your constructors into one "master" constructor using
this(...), and put the real initialization there. If validation rules change later, you edit one constructor instead of three. This pattern is called constructor telescoping done right.
this() and super(): chaining explained
Two special calls appear only inside constructors, and each must be the first statement:
this(...)calls another constructor in the same class.super(...)calls a constructor of the parent class.
Because both must come first, a constructor can use only one of them. When a subclass object is built, the parent's constructor always runs before the child's body, so the inherited fields exist before the child touches them.
class Animal {
String name;
Animal(String name) {
this.name = name;
System.out.println("Animal built");
}
}
class Dog extends Animal {
String breed;
Dog(String name, String breed) {
super(name); // parent constructor runs first
this.breed = breed;
System.out.println("Dog built");
}
}
public class Main {
public static void main(String[] args) {
new Dog("Bruno", "Labrador");
// Output:
// Animal built
// Dog built
}
}
If you don't write super(...), the compiler inserts a call to the parent's no-arg constructor. If the parent has no no-arg constructor, your code won't compile until you call super(...) explicitly — the same rule that governs inheritance.
The copy constructor pattern
Java has no built-in copy constructor like C++, but the pattern is easy: write a constructor that takes an object of the same class and copies its fields.
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
Point(Point other) { // copy constructor
this.x = other.x;
this.y = other.y;
}
}
public class Main {
public static void main(String[] args) {
Point p1 = new Point(3, 4);
Point p2 = new Point(p1); // independent copy
p2.x = 99;
System.out.println(p1.x + " " + p2.x); // 3 99
}
}
Because p2 is a separate object with copied values, changing p2.x leaves p1 untouched. This is the safe way to duplicate an object without the subtle sharing problems that come from just assigning p2 = p1 (which would make both names point at the same object).
Constructors and interviews
Constructors generate a steady stream of fresher interview questions because they sit at the intersection of objects, inheritance, and overloading:
- "When does Java give you a default constructor?" — only when you write none.
- "Can a constructor be
private?" — yes, used in singletons and factory patterns. - "Can you call one constructor from another?" — yes, with
this(...)as the first statement. - "What runs first in
new Dog(...)?" — the parent constructor viasuper(...).
Being crisp on these separates candidates who memorized syntax from those who understand object construction.
Where to go next
Constructors initialize state; the next questions are how that state is protected and how objects relate. Move on to encapsulation to see why constructors often pair with private fields, and to method overloading since constructor overloading is the same idea applied to construction.
For guided practice that turns these rules into instinct — chaining, overloading, and the framework requirement for a no-arg constructor — the fundamentals track of the Java Full Stack course drills them with real project code, and the Java learning hub shows how it all fits together.
Frequently Asked Questions
What is the difference between a constructor and a method?
When does Java provide a default constructor?
What is constructor overloading?
What is the difference between this() and super() in constructors?
Does Java have a built-in copy constructor like C++?
Want to Build Your Career in Java Full Stack with AI?
Join CodeBegun and train with working industry engineers — Explore the Program

