Constructors and Fields

Basic Java
≈ 4 min read

Fields store an object's state

On the previous page, we already created classes and objects. Now let's look at where an object gets its data from. Variables declared inside a class but outside methods are called fields. An object stores its state in these fields.

class Player {
    String name;
    int level;
}

Player first = new Player();
first.name = "Alex";
first.level = 5;

Player second = new Player();
second.name = "Mia";
second.level = 2;

first and second have their own field values. Both objects are created from the same Player class, but their state can be different.

Initial field values

If a field is not explicitly given a value when an object is created, Java assigns it a default value. For numeric types it is 0, for boolean it is false, and for reference types it is null.

class Player {
    String name; // null
    int level;   // 0
}
This rule applies specifically to fields. Java will not let you read a local variable inside a method until a value has been assigned to it.

If a field has a natural initial value, you can specify it directly in the declaration:

class Player {
    String name;
    int level = 1;
}

A constructor sets the initial state

Often an object should receive important data as soon as it is created. For this, a class has a constructor — a special block of code that runs when new is called. A constructor has the same name as the class, and it does not declare a return type.

class Player {
    String name;
    int level;

    Player(String name, int level) {
        this.name = name;
        this.level = level;
    }
}

Player player = new Player("Alex", 5);

In the expression new Player("Alex", 5), Java creates an object and calls the matching constructor. The name and level parameters receive the passed values, and then those values are stored in the fields of the new object.

The expression this.name means the name field of the current object. Here, this helps distinguish the field from the parameter with the same name. The same thing happens with this.level.

A class can have multiple constructors

Like methods, constructors can be overloaded: the same class can support several ways to create an object as long as the parameter lists are different.

class Player {
    String name;
    int level;

    Player(String name) {
        this(name, 1);
    }

    Player(String name, int level) {
        this.name = name;
        this.level = level;
    }
}

The first constructor is useful when the object should start at level one. The call this(name, 1) delegates the work to another constructor of the same class, so the shared initialization does not have to be duplicated.

When Java provides a constructor for you

If a class declares no constructors at all, the compiler adds a no-argument constructor. That is why the call new Player() worked in the first example.

But as soon as you declare at least one constructor yourself, that automatically added no-argument constructor is no longer provided.

class Player {
    String name;

    Player(String name) {
        this.name = name;
    }
}

Player player = new Player("Alex");
Do not confuse a constructor with a regular method. A constructor has no return type — not even void. If you write void Player(), it will be a regular method named Player.