skip to content

Constructor Patterns & Constraints

Practical constructor idioms: copy constructors, private constructors for singletons, utility classes and factories, why constructors are not inherited, and the cost of throwing from one. Useful for design questions about controlling how instances are created.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

Are constructors inherited in Java? Explain how subclass construction actually works.

level: juniorimportance: must knowfreq 65%

answer

  1. Constructors are NOT inherited
  2. Methods/fields inherited; constructors/static-init not
  3. First line: this(...) or super(...), else implicit super()
  4. Parent constructed before child, up to Object
  5. Parent with only param ctor → child must call super(args)

basics

~20 s

No. Constructors are not inherited. A subclass must define its own constructors. When a subclass object is built, its constructor first calls a superclass constructor (with super(...), or an implicit super() if you omit it).

solid answer

~40 s

Constructors are **not** inherited in Java — they are not members in the way methods and fields are, so a subclass does not receive its parent's constructors. Each class defines its own. However, construction is *chained*: the first thing any constructor does is invoke a superclass constructor, either explicitly via `super(args)` as the first statement, or implicitly via a no-arg `super()` the compiler inserts when you write neither `super(...)` nor `this(...)`. This runs the parent's initialization before the child's, all the way up to `Object`. A consequence: if the superclass has *only* a parameterized constructor (no accessible no-arg one), the subclass must explicitly call `super(args)`, otherwise the implicit `super()` fails to compile. Because constructors aren't inherited, a subclass that wants to expose the same construction signatures must redeclare them and delegate with `super(...)`.

code

java · 10 lines
java
class Animal {
    Animal(String name) { }      // only a parameterized constructor
}

class Dog extends Animal {
    Dog(String name) {
        super(name);             // REQUIRED: no implicit super() target exists
    }
    // Dog() {}  // would NOT compile: implicit super() finds no Animal()
}

go deeper

for a junior

States clearly that constructors are not inherited and that each class declares its own.

for a middle

Explains constructor chaining (implicit/explicit super()) and the no-arg-parent-constructor gotcha with a correct fix.

for a senior

Connects chaining order to initialization correctness and final-field setup, and reasons about exposing parent signatures by redeclaration; aware of JDK 22 statements-before-super.

for a principal

Designs class hierarchies to minimize fragile constructor chains (favoring composition/builders/records), and sets conventions for how subclasses surface or restrict construction across a library's API.

## The short answer **Constructors are not inherited.** If `Dog extends Animal`, `Dog` does not automatically get `Animal`'s constructors. You cannot do `new Dog("some animal arg")` just because `Animal` has a constructor with that signature — unless `Dog` declares such a constructor itself. ## Why not? What *is* inherited? Inheritance means a subclass receives the **members** (instance methods and fields) of its superclass. A constructor is a special initializer tied to a specific class name; it is not a normal member and is not passed down. (Intuitively: a constructor's name *is* the class name, so an inherited one wouldn't even have the right name.) Methods and fields *are* inherited; constructors and static initializers are not. ## How a subclass object is built: constructor chaining Even though constructors aren't inherited, building a subclass object *does* run the superclass's constructor. Here's the rule: > The **first statement** of every constructor is either `this(...)` (call another constructor in the same class) or `super(...)` (call a superclass constructor). If you write neither, the compiler inserts an implicit `super()` — a call to the superclass's **no-argument** constructor. So construction flows *upward first*: the parent is fully initialized before the child's own constructor body runs. ```java class Animal { Animal() { System.out.println("Animal ctor"); } } class Dog extends Animal { Dog() { // implicit super(); runs here first System.out.println("Dog ctor"); } } // new Dog() prints: Animal ctor then Dog ctor ``` The chain continues all the way up to `java.lang.Object`, whose constructor runs first of all. ## The classic gotcha: superclass has no no-arg constructor If the superclass declares *only* a constructor that takes arguments, there is no no-arg `super()` for the compiler to insert. Then the subclass **must** call `super(args)` explicitly as its first statement, or it won't compile: ```java class Animal { Animal(String name) { /* ... */ } // only a parameterized ctor } class Dog extends Animal { Dog() { super("Rex"); // REQUIRED — no implicit super() exists } } ``` This is the most common interview trap: "why doesn't my subclass compile?" — because the implicit `super()` refers to a no-arg constructor the parent doesn't have. ## A note on JDK 22+ Before Java 22, `super(...)`/`this(...)` had to be the literal first statement. JDK 22 added **statements before super()** (a preview/finalized feature) allowing limited code (e.g. argument validation) before the explicit super call, but the super/this call must still happen before any reference to the new instance. The conceptual model — parent initialized before child — is unchanged. ## Consequence for API design Because constructors aren't inherited, if you want a subclass to offer the same construction signatures as its parent, you must **redeclare** each one and delegate: `Dog(String name) { super(name); }`. There is no shortcut that re-exposes parent constructors.

  • Why does a subclass fail to compile if its superclass only has a parameterized constructor and the subclass doesn't call super explicitly?
    When you write no super(...)/this(...), the compiler inserts an implicit super() — a call to a no-arg superclass constructor. If the superclass has no accessible no-arg constructor, that implicit call can't be resolved, so it's a compile error. You fix it by writing super(args) explicitly.
  • If constructors aren't inherited, how does the superclass's constructor still run?
    Through constructor chaining: every constructor's first action is a super(...) (explicit or implicit) call, which executes the parent constructor before the child's body. So the parent is initialized even though its constructor wasn't 'inherited' as a callable member of the subclass.

saying these in an interview costs you the question

  • Saying constructors are inherited like methods
  • Believing you can call new Subclass(args) using only the parent's matching constructor
  • Forgetting the implicit super() requires a no-arg parent constructor
  • Thinking the child constructor body runs before the parent's

context

open as a page

What is the copy constructor pattern in Java, and how do you implement a correct one?

level: middleimportance: should knowfreq 55%

basics

~20 s

A copy constructor takes another object of the same class and creates a new object with the same values. You write a constructor whose single parameter is the same type, then copy each field into the new object.

open as a page

What are the common reasons to make a constructor private in Java?

level: middleimportance: should knowfreq 60%

basics

~20 s

A private constructor stops other code from creating objects with new. You use it to force creation through factory methods, to make a singleton (only one instance), or for utility classes that hold only static members and should never be instantiated.

open as a page

Can a constructor throw a checked exception in Java, and what are the implications?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Yes. A constructor can declare throws and throw checked exceptions just like a method. If it throws, the object is not created, so the caller must handle or declare the exception, and there is no half-built object returned.

open as a page

Why is an enum often the best way to implement a singleton compared to a private-constructor class?

level: principalimportance: nice to knowfreq 35%

basics

~20 s

An enum with one constant is a singleton that Java guarantees stays single. Its constructor is private automatically, and Java prevents extra instances from reflection or deserialization — problems a hand-written private-constructor singleton must defend against itself.

open as a page