Skip to main content

SF-0307 · Concept · Easy

What is a constructor?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

A constructor is a special method whose only job is to set up an instance of a class. It runs once, the moment a new ClassName() expression evaluates. Constructors share the class’s name, take any parameters you want, and have no return type — not even void.

The basics

public class Order {
    private String orderNumber;
    private Decimal total;

    public Order(String orderNumber, Decimal total) {  // <-- constructor
        this.orderNumber = orderNumber;
        this.total = total;
    }
}

Order o = new Order('ORD-001', 99.99); // calls the constructor

A few rules:

  • Name must match the class name exactly, including case.
  • No return type. Not void, not Order, not anything. The constructor implicitly returns the new instance.
  • Access modifier controls who can call new ClassName(...). A private constructor blocks new from outside the class — the singleton pattern.

The default no-arg constructor

If you write no constructors, Apex generates a hidden public no-arg one:

public class OrderService {
    // no constructor defined
}

OrderService s = new OrderService(); // works — Apex generated the no-arg

The moment you write any constructor with parameters, the default no-arg disappears. To keep new OrderService() callable, define it explicitly:

public class OrderService {
    public OrderService() { }                  // explicit no-arg
    public OrderService(String name) { ... }   // overloaded
}

Constructor overloading

Apex supports overloading by parameter count and type:

public class Order {
    public Order() { }
    public Order(String number) { ... }
    public Order(String number, Decimal total) { ... }
    public Order(Account a) { ... }
}

The platform picks the matching signature at compile time.

Calling another constructor with this(...)

You can chain constructors to avoid repeating initialization logic:

public class Order {
    public Order() {
        this('ORD-NEW', 0);
    }
    public Order(String number) {
        this(number, 0);
    }
    public Order(String number, Decimal total) {
        this.orderNumber = number;
        this.total = total;
    }
}

this(...) must be the first statement in the constructor that uses it. Apex enforces this.

Constructors in inheritance

When a subclass extends a parent, the parent’s constructor runs first. If the parent has any constructor and none is no-arg, the child must explicitly call one:

public virtual class Account_Base {
    public Account_Base(String name) { ... }
}

public class Account_Premium extends Account_Base {
    public Account_Premium(String name) {
        super(name);   // must call parent's constructor
    }
}

super(...) works like this(...) — must be the first statement.

The singleton pattern with a private constructor

public class ConfigManager {
    private static ConfigManager instance;

    private ConfigManager() { }  // outside code can't `new` this

    public static ConfigManager getInstance() {
        if (instance == null) instance = new ConfigManager();
        return instance;
    }
}

new ConfigManager() from outside the class produces a compile error. Callers must go through getInstance().

What you typically put in a constructor

  • Assign final fields (Apex’s term for static final is just static final).
  • Validate parameters — throw an exception if input is bad.
  • Set up dependencies — references to other objects, default values.

What you should avoid:

  • SOQL queries unless absolutely necessary. Constructors run for every new call; SOQL there can quietly add up.
  • DML — almost always a smell. Constructors shouldn’t have side effects on the database.
  • HTTP callouts — same reason.
  • Complex logic — keep the constructor minimal; move setup work to named static factory methods if it gets involved.

A static factory alternative

public class Order {
    private Order() {}  // private — force factory usage

    public static Order fromAccount(Account a) {
        Order o = new Order();
        o.orderNumber = 'ORD-' + a.Id;
        o.total = a.AnnualRevenue;
        return o;
    }
}

Order o = Order.fromAccount(someAccount);

Named static factories (Order.fromAccount, Order.empty, Order.withDefaults) are clearer than overloaded constructors when the same parameter list could mean different things.

What interviewers are really looking for

The naming check: “method with the class name, called on new.” Strong signals: (1) no return type — not even void, (2) Apex generates a default no-arg only if you write no constructors, (3) constructor chaining via this(...) as the first statement, (4) super(...) for parent constructors in inheritance, (5) the singleton pattern with a private constructor, (6) don’t do SOQL/DML in constructors — it scales badly.

Verified against: Apex Developer Guide — Constructors. Last reviewed 2026-05-17.