A constructor initialises a new object. Java runs static setup once per class and then a fixed sequence for every new.
Kinds of constructors
| Kind | What it is |
|---|---|
| Default | Added by the compiler only if you write no constructor at all: no args, calls super(). |
| No-arg | One you write yourself with no parameters. |
| Parameterized | Takes arguments to set up state. |
| Copy | Takes another instance of the same class: Point(Point other) (Java has no built-in copy constructor). |
| Private | Prevents outside new — singletons, factories, utility classes. |
Overloading and chaining with this(...)
public class Main {
public static void main(String[] args) {
System.out.println(new Pizza());
System.out.println(new Pizza("large"));
System.out.println(new Pizza("small", 3));
}
}
class Pizza {
private final String size;
private final int toppings;
Pizza() { this("medium"); } // delegates
Pizza(String size) { this(size, 1); } // delegates
Pizza(String size, int toppings) { // the one "real" constructor
this.size = size;
this.toppings = toppings;
}
@Override public String toString() { return size + " pizza, " + toppings + " topping(s)"; }
}medium pizza, 1 topping(s)
large pizza, 1 topping(s)
small pizza, 3 topping(s)Initializer blocks
The full initialization order
public class Main {
public static void main(String[] args) {
System.out.println("-- first new Child()");
new Child();
System.out.println("-- second new Child()");
new Child();
}
}
class Parent {
static { System.out.println("1. Parent static block"); }
{ System.out.println("3. Parent instance block"); }
Parent() { System.out.println("4. Parent constructor"); }
}
class Child extends Parent {
static { System.out.println("2. Child static block"); }
private String name = init();
{ System.out.println("6. Child instance block"); }
Child() { System.out.println("7. Child constructor"); }
private String init() { System.out.println("5. Child field initializer"); return "child"; }
}-- first new Child()
1. Parent static block
2. Child static block
3. Parent instance block
4. Parent constructor
5. Child field initializer
6. Child instance block
7. Child constructor
-- second new Child()
3. Parent instance block
4. Parent constructor
5. Child field initializer
6. Child instance block
7. Child constructorStatic, parent first
Superclass static fields/blocks, then subclass static fields/blocks — once per class, in textual order.
Parent instance part
super(...)runs first: parent field initialisers + instance blocks (textual order), then parent constructor body.Child instance part
Child field initialisers + instance blocks in textual order, then the child constructor body.
Pitfall: calling an overridable method from a constructor
public class Main {
public static void main(String[] args) {
new Sub();
}
}
class Base {
Base() { describe(); } // dynamic dispatch — calls Sub.describe()
void describe() { System.out.println("Base"); }
}
class Sub extends Base {
private String label = "ready";
@Override void describe() { System.out.println("Sub label = " + label); }
}Sub label = nullCan a constructor be private? Why would you do that?
Is a constructor inherited? Can it be overridden?
Can a constructor return a value or be final/static?
In what order do static blocks, instance blocks and constructors run?