new. It has the same name as the class, has no return type, and its job is to put the new object into a valid starting state. If you write none, the compiler adds a no-argument default constructor.
this(...) in the same class, or super(...) in the parent), and the bodies then finish in reverse order, parent first. This page covers the types of constructors, chaining, copy constructors and their shallow-copy trap, private constructors, and why constructors are not inherited, with the real output and compiler errors from JDK 25.
Versions. Every program on this page was compiled and run on JDK 25.0.4.1 (Temurin, LTS, build 25.0.4.1+1-LTS). Where Java 8 behaved differently the text says so. The compiler errors and console output are quoted verbatim from those runs; the “Download” links at the end of each section point to the exact .java files.
Types of constructors
| Type | What it is | Notes |
|---|---|---|
| Default (implicit) | Added by the compiler when you declare no constructor | No arguments; calls super(); has the class’s access level |
| No-argument (explicit) | You write Foo() { ... } | Needed if you add other constructors and still want new Foo() |
| Parameterised | Takes arguments to initialise fields | Can be overloaded freely |
| Copy | Takes another object of the same class | Not special in Java: you write it yourself |
| Private | Only code inside the class can call it | Used for singletons, factories and utility classes |
class Plain { }
$ java ConstructorsDemo.java
-- default constructor: the compiler writes it --
declared constructors of Plain: [Plain()]
The compiler really did write Plain(). The catch is in the table’s first row: the moment you declare any constructor, the default one disappears, and new Account() stops compiling (shown in the errors section below).
Constructor chaining: this() and super()
this(...) calls another constructor in the same class, which is how you avoid repeating initialisation code. super(...) calls a constructor in the parent class. Each constructor can make one such call, and it has to be the first statement in the constructor (Java 25 relaxes this; see below). If you write neither, the compiler inserts super() for you.
class Person {
Person(String name) { System.out.println(" Person(" + name + ")"); }
}
class Employee extends Person {
Employee(String name, int level) {
super(name);
System.out.println(" Employee(" + name + ", " + level + ")");
}
Employee(String name) {
this(name, 1);
System.out.println(" Employee(" + name + ")");
}
}
class Manager extends Employee {
Manager(String name) {
super(name);
System.out.println(" Manager(" + name + ")");
}
}
$ java ConstructorsDemo.java
-- chaining: this(...) inside a class, super(...) up the hierarchy --
Person(Ravi)
Employee(Ravi, 1)
Employee(Ravi)
Manager(Ravi)
Read the output against the diagram. Manager called super(name), which ran Employee(name), which called this(name, 1), which called super(name) on Person. The parent Person body ran first, and the bodies unwound back down to Manager.
| this(…) | super(…) | |
|---|---|---|
| Calls | Another constructor of the same class | A constructor of the parent class |
| Purpose | Reuse initialisation code | Initialise the inherited part first |
| Position | First statement (before Java 25 rules, see below) | First statement (before Java 25 rules, see below) |
| Both in one constructor? | No: a constructor makes one or the other | No |
| If omitted | Nothing is inserted | super() is inserted |
Java 25: you can run code before super()
Before Java 25 the rule was strict: the call tothis(...) or super(...) had to be the very first statement, so validating an argument before calling the parent was awkward. Java 25 finalises JEP 513 (flexible constructor bodies): you may put statements, such as argument validation, before the super(...) call, provided they do not read this or call instance methods. The details and examples are in Flexible Constructor Bodies in Java 25 (JEP 513). The chaining behaviour on this page is unchanged by it.
Copy constructors, and the shallow-copy trap
Java has no built-in copy constructor like C++. It is just a constructor that takes the same type:class Point {
int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
Point(Point other) { this(other.x, other.y); }
public String toString() { return "(" + x + "," + y + ")"; }
}
$ java ConstructorsDemo.java
-- copy constructor makes an independent object --
p=(1,2) q=(99,2)
Changing q.x left p.x alone, so they are independent. That only works because the fields are primitives. If a field is a reference, copying it copies the reference, not the object it points to:
class Team {
String[] members;
Team(String[] m) { members = m; }
Team(Team other) { this.members = other.members; }
}
$ java ConstructorsDemo.java
-- shallow copy trap --
t1.members[0] = CHANGED
Both Team objects share the same array, so changing it through t2 changed what t1 sees. The fix is a deep copy: this.members = other.members.clone() for an array, or a new collection built from the old one (see Immutable Collections in Java for why immutable collections avoid this class of bug).
Private constructors
Making a constructor private means nobody outside the class can writenew. The class then offers a static factory method, or nothing at all:
class Config {
private static final Config INSTANCE = new Config();
private Config() { }
static Config get() { return INSTANCE; }
}
$ java ConstructorsDemo.java
-- private constructor: the only way in is a factory --
true
Config.get() == Config.get() is true, so both calls returned the same single instance (a singleton). The same trick, with no factory at all, is how utility classes such as java.lang.Math stop themselves being instantiated.
Constructors are not inherited
A subclass does not get its parent’s constructors. It has only the ones it declares (or the default one), and each must call a parent constructor. This is why the earlier example,Child, has one constructor and Parent has one, and new Child(5) would not compile:
class Parent { Parent(int x) { } }
class Child extends Parent { Child() { super(1); } }
$ java ConstructorsDemo.java
-- constructors are not inherited --
Child constructors: 1, Parent constructors: 1
The compiler errors in the next section show the failure for real.
The five compile errors constructors cause
BrokenConstructors.java breaks five rules in one file; every message below is from the real compiler:class Person {
Person(String name) { }
}
class Student extends Person {
Student() { } // no super(...) written: javac inserts super(), which does not exist
}
class Account {
Account(int id) { }
}
class UsesDefault {
void make() { new Account(); } // default constructor vanished when Account declared its own
}
class Config {
private Config() { }
}
class Outside {
void make() { new Config(); }
}
class SelfLoop {
SelfLoop() { this(1); }
SelfLoop(int x) { this(); }
}
class P2 { P2(int x) { } }
class C2 extends P2 { C2() { super(1); } }
class UseC2 { void make() { new C2(5); } } // C2 does not inherit P2(int)
public class BrokenConstructors { public static void main(String[] a) { } }
$ javac BrokenConstructors.java
BrokenConstructors.java:5: error: constructor Person in class Person cannot be applied to given types;
Student() { } // no super(...) written: javac inserts super(), which does not exist
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
BrokenConstructors.java:11: error: constructor Account in class Account cannot be applied to given types;
void make() { new Account(); } // default constructor vanished when Account declared its own
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
BrokenConstructors.java:17: error: Config() has private access in Config
void make() { new Config(); }
^
BrokenConstructors.java:21: error: recursive constructor invocation
SelfLoop(int x) { this(); }
^
BrokenConstructors.java:25: error: constructor C2 in class C2 cannot be applied to given types;
class UseC2 { void make() { new C2(5); } } // C2 does not inherit P2(int)
^
required: no arguments
found: int
reason: actual and formal argument lists differ in length
5 errors
In order: (1) Student() has no explicit super(...), so the compiler inserts super(), which Person does not have; (2) declaring Account(int) removed the default constructor; (3) a private constructor cannot be called from another class; (4) two constructors calling each other is a recursive invocation; (5) C2 does not inherit P2(int), and there is no C2(int). Cases 1 and 2 are by far the most common.
Calling an overridable method from a constructor. The parent constructor runs before the subclass fields are initialised. If it calls a method the subclass overrides, that method runs on a half-built object and sees default values (0,null). Keep constructors to simple assignments, or call onlyprivateorfinalmethods.
Going deeper
- Initialisation order of static and instance blocks around constructors: static Keyword in Java
- Constructors in abstract classes and interfaces: Abstract Class vs Interface in Java
- Fields set once in a constructor: final vs finally vs finalize
- Who can call a constructor: Access Modifiers in Java
- Constructors in the running bank example: OOPs Concepts in Java
- Language rules: JLS 8.8, Constructor Declarations
Download the code. ConstructorsDemo.java · BrokenConstructors.java.
Run a runnable one withjava File.java(JDK 11 or later; JDK 25 recommended). Files starting withBrokenare meant to fail to compile.
Common interview questions
1. What is a constructor in Java?
A special member with the class name and no return type that runs on new to initialise the object.
2. What is the difference between a constructor and a method?
A constructor has the class name, no return type, is called by new and cannot be called like a normal method. A method has a return type and is called on an object or class.
3. What is the default constructor?
A no-argument constructor the compiler adds when a class declares none. It disappears as soon as you declare any constructor.
4. Can a constructor be private?
Yes. Only code in the class can call it, which is used for singletons, static factories and utility classes.
5. Can constructors be overloaded? Overridden?
Overloaded yes, overridden no. They are not inherited, so there is nothing to override.
6. What is constructor chaining?
One constructor calling another, with this(...) in the same class or super(...) in the parent, so initialisation code is not repeated.
7. What is the difference between this() and super()?
this(...) calls a constructor of the same class; super(...) calls a constructor of the parent. A constructor can make only one of the two calls.
8. Does the parent constructor always run?
Yes. If you do not write super(...) the compiler inserts super(), and the code fails to compile if the parent has no no-argument constructor.
9. Is there a copy constructor in Java?
Not built in. You write a constructor that takes the same type, and you must deep copy reference fields yourself.
10. Can a constructor be final, static or abstract?
No to all three. Constructors are not inherited (so final and abstract are meaningless) and they initialise a particular object (so static makes no sense).
11. Can a constructor throw an exception?
Yes, including checked exceptions. The caller must handle them.
12. What happens if a constructor calls an overridden method?
The overriding method runs before the subclass fields are initialised and sees default values.
13. What changed with JEP 513 in Java 25?
Statements that do not use this may now appear before super(...) or this(...), which makes argument validation easier.
14. Can a constructor return a value?
No. It has no return type; return; is allowed only to exit early.
15. What is the order of initialisation when you create an object?
Parent static, child static (once per class), then parent instance initialisers and constructor, then child instance initialisers and constructor.
Common mistakes
- Adding a parameterised constructor and forgetting the default one disappeared. Add the no-argument constructor back if code needs it.
- A parent class with no no-argument constructor. Every subclass constructor must call
super(...)explicitly. - Copy constructors that copy references. Shared mutable state surprises callers; deep copy.
- Doing heavy or failing work in a constructor. Prefer a factory method that can return or throw clearly.
- Calling overridable methods from a constructor. They see an unfinished object.
- Two constructors that call each other. The compiler rejects recursion, but longer cycles are just as wrong.
FAQ
What is a constructor in Java?
A constructor is a special block with the same name as its class and no return type. It runs when you create an object with new and sets up the object’s initial state.
What are the types of constructors in Java?
Default (added by the compiler), no-argument, parameterised, copy (a convention you write yourself) and private. Constructors can be overloaded but not inherited or overridden.
What is the difference between this() and super() in Java?
this() calls another constructor in the same class and super() calls a constructor in the parent class. Only one can be used per constructor, and the compiler inserts super() if you write neither.
Can a constructor be private in Java?
Yes. A private constructor can only be called from inside its own class, which is used for singletons, static factory methods and utility classes.
Are constructors inherited in Java?
No. A subclass has only the constructors it declares, and each one must call a parent constructor with super(…), explicitly or implicitly.
Where to go next
- OOPs Concepts in Java (objects and classes)
- Inheritance Example in Java (a short practice program)
- Flexible Constructor Bodies in Java 25 (JEP 513)
- Top 40 Java Collections Interview Questions (copy constructors on collections)
- Top 40 Java Concurrency Interview Questions (safe publication of objects built in constructors)
- Java Interview Preparation Guide
No Comments yet!