Constructors & this

In the last lesson, building a BankAccount meant creating it with new and then setting owner and balance on separate lines afterward. That leaves a window where the object exists but is only half set up — nothing stops you from calling deposit before owner was ever assigned. A constructor closes that window by making setup part of creation itself.

What a constructor is

A constructor looks like a method, but it has no return type at all — not even void — and its name always matches the class exactly. It's the code that runs automatically the instant new creates an object, and its whole job is usually to get the object's fields into a valid starting state.

</> BankAccount.java
public class BankAccount {
    String owner;
    double balance;

    BankAccount(String owner, double balance) {
        this.owner = owner;
        this.balance = balance;
    }

    void deposit(double amount) {
        this.balance = this.balance + amount;
    }
}
</> ConstructorDemo.java
public class ConstructorDemo {
    public static void main(String[] args) {
        BankAccount account = new BankAccount("Priya", 1000.0);
        account.deposit(250.0);

        System.out.println(account.owner + ": $" + account.balance);
    }
}
Output
Priya: $1250.0

There's no separate step anymore where the account briefly exists without an owner or a balance — by the time new BankAccount("Priya", 1000.0) finishes running, the object is already fully formed. If you tried to write new BankAccount() with no arguments now, the compiler would reject it, because it no longer knows of any constructor that takes zero arguments — defining even one constructor removes Java's normally-automatic no-argument one.

Why this exists

Look closely at the constructor's parameter names: owner and balance, exactly matching the field names they're meant to fill. That's deliberate and common — it's the most obvious name for a parameter to have. But it creates a genuine ambiguity: inside the constructor, does owner refer to the parameter or the field? Java resolves this by always preferring the closer one, the parameter, which means plain owner = owner; would just assign the parameter to itself and leave the field untouched.

this is how you break that tie. this.owner unambiguously means "the field on the current object," no matter what else is named owner in the surrounding scope. It's not just for constructors either — this.balance inside deposit reads perfectly well without a naming collision to resolve, but it's still valid, and some developers use it everywhere for clarity. The one place it's load-bearing is exactly this situation: a parameter shadowing a field of the same name.

Overloading constructors

Just like methods, a class can have multiple constructors, as long as their parameter lists differ. This lets you offer sensible defaults for callers who don't want to specify everything:

</> BankAccount.java
public class BankAccount {
    String owner;
    double balance;

    BankAccount(String owner, double balance) {
        this.owner = owner;
        this.balance = balance;
    }

    BankAccount(String owner) {
        this(owner, 0.0);
    }
}
</> OverloadedConstructorDemo.java
public class OverloadedConstructorDemo {
    public static void main(String[] args) {
        BankAccount funded = new BankAccount("Marcus", 400.0);
        BankAccount fresh = new BankAccount("Tanya");

        System.out.println(funded.owner + ": $" + funded.balance);
        System.out.println(fresh.owner + ": $" + fresh.balance);
    }
}
Output
Marcus: $400.0
Tanya: $0.0

The single-argument constructor doesn't repeat the setup logic — it calls the two-argument constructor with this(owner, 0.0), passing along 0.0 as a sensible default starting balance. this(...), used this way as the very first line of a constructor, means "run another constructor of this same class first." It keeps the actual field-assignment logic written in exactly one place, so a future change to how accounts get initialized only needs to happen once.

Note: this(...) calling another constructor and this.field referring to a field look similar but do different jobs — the first must be the very first line of a constructor and can only appear there, while the second can appear almost anywhere inside instance methods or constructors.