Start learning free

LESSON 178 OF 344 · OBJECT-ORIENTED PROGRAMMING

Constructors in Java: Initializing Objects with this

Lesson Read the full explanation

TL ; DR:

  • A constructor is a special method that runs automatically when you create an object with new. It's used to set up the object's initial state.


  • In Java, a constructor has the same name as the class and no return type:

    class Dog {
        public String name;
        public int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    

  • Then create objects with arguments: new Dog("Rex", 4) — the constructor fills in the fields for you.



Full lesson:

In the previous lesson you set fields after creating the object:

Dog dog = new Dog();
dog.name = "Rex";
dog.age = 4;

That works, but it's noisy and easy to forget. Constructors let you initialize the fields the moment new Dog(...) is called.


Defining a constructor

A Java constructor has two distinguishing features:

  • Its name is exactly the class name (Dog for a Dog class).

  • It has no return type — not even void.

public Dog(String name, int age) {
    this.name = name;
    this.age = age;
}

The this keyword

The parameter name and the field name have the same identifier. Without this, both sides of name = name; would refer to the parameter (the local one wins). this is a built-in reference to "the current object", so this.name is the field, and bare name is the parameter.


Calling the constructor

Dog rex  = new Dog("Rex", 4);
Dog luna = new Dog("Luna", 7);

By the time these lines finish, rex.name is already "Rex", rex.age is 4, and the same for Luna.


The default constructor

If you don't write any constructor, Java provides a hidden no-arg one for free — that's why new Dog() worked in earlier lessons. The moment you define your own constructor, that freebie disappears: from now on you must call new Dog with the arguments you specified.


Your task

The Dog class already has the name and age fields. Add a constructor that takes a String name and an int age and assigns them using this. Then in mainFunction, create two dogs:

Dog rex  = new Dog("Rex", 4);
Dog luna = new Dog("Luna", 7);

Expected output:

Rex is 4
Luna is 7
STEP 1 OF 2
    Ctrl + Enter to check

    JAVA · OBJECT-ORIENTED PROGRAMMING

    Constructors in Java, explained

    What a constructor is

    When fields are public, you can create an object and then fill it in:

    Dog dog = new Dog();
    dog.name = "Rex";
    dog.age = 4;
    

    That works, but it takes three lines per dog, and it is easy to forget one of them and leave a field at its default. A constructor is a special piece of code that runs automatically when new creates an object, so the object starts out fully set up.

    Defining a constructor

    A Java constructor looks like a method with two differences:

    • its name is exactly the class name, so Dog for the class Dog;
    • it has no return type, not even void.
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
    

    The parameters are ordinary local variables. The constructor body copies them into the fields, so every object stores its own values.

    The this keyword

    In the constructor above, the parameter name and the field name have the same identifier. Inside the constructor, a bare name means the parameter, because the closest declaration wins. this is a reference to the object being built, so this.name is the field and plain name is the parameter.

    This is the most common constructor bug. If you write name = name;, the code compiles and runs without any error, but it assigns the parameter to itself and never touches the field. A quick check shows it:

    class Pup {
        public String name;
        public int age;
    
        public Pup(String name, int age) {
            name = name;
            this.age = age;
        }
    }
    
    Pup p = new Pup("Rex", 4);
    System.out.println(p.name + " " + p.age);
    

    This prints:

    null 4
    

    The field name kept its default value, null, while age was set correctly.

    Calling the constructor

    You pass the arguments in the parentheses after new, in the order of the parameters:

    Dog rex  = new Dog("Rex", 4);
    Dog luna = new Dog("Luna", 7);
    

    By the time each line finishes, rex.name is already "Rex" and rex.age is 4. The same holds for luna. The arguments must match the constructor's parameters in number and type, otherwise the program doesn't compile.

    The default constructor

    If a class declares no constructor, Java supplies a hidden one with no parameters. That is why new Dog() worked in the earlier lessons. The moment you write any constructor yourself, the hidden one disappears. After you add Dog(String name, int age), the call new Dog() no longer compiles, and every new Dog must pass a name and an age. If you still want a no-argument version, you have to write it yourself.

    More than one constructor

    A class may have several constructors with different parameter lists. One can also call another with this(...), as long as that call is the first statement. This lets a shorter constructor supply a default:

    class Cat {
        public String name;
        public int age;
    
        public Cat(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public Cat(String name) {
            this(name, 1);
        }
    }
    

    With these two constructors, new Cat("Tom") creates a one-year-old cat named Tom, and new Cat("Kit", 7) sets both values. Java picks the constructor whose parameters match the arguments you pass.

    The lesson's exercise, step by step

    The starter code gives Dog its two public fields and a mainFunction that prints from two variables, rex and luna, that you must create. There are two steps:

    1. Add the constructor inside Dog, below the fields, with the signature public Dog(String name, int age). Use this.name and this.age on the left of each assignment.
    2. Create the dogs in mainFunction with new Dog("Rex", 4) and new Dog("Luna", 7).

    The finished program:

    class Dog {
        public String name;
        public int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    class Solution {
        public void mainFunction() {
            Dog rex = new Dog("Rex", 4);
            Dog luna = new Dog("Luna", 7);
            System.out.println(rex.name + " is " + rex.age);
            System.out.println(luna.name + " is " + luna.age);
        }
    }
    

    It prints:

    Rex is 4
    Luna is 7
    

    Common mistakes

    • Writing a return type. public void Dog(String name, int age) is not a constructor. Java treats it as an ordinary method that happens to be named Dog, and new Dog("Rex", 4) then fails to compile.
    • Misspelling the class name. The constructor name must match the class exactly, including capitalization.
    • Forgetting this. When parameters share the fields' names, name = name; silently does nothing useful. Using different parameter names, such as dogName, also avoids the problem.
    • Swapping arguments. new Dog(4, "Rex") doesn't compile, because an int is not a String. When two parameters have the same type, swapped arguments compile but give wrong data.
    • Calling new Dog() after adding a constructor. The default constructor is gone, so the call needs matching arguments.

    Key takeaways

    • A constructor runs when new creates an object and sets up its initial state.
    • Its name is the class name, and it has no return type.
    • this.field = parameter; is the standard way to store a parameter that has the same name as a field.
    • Java gives a class a no-argument constructor only if you write none yourself.
    • A class can have several constructors, and one can call another with this(...).
    Keep going with JavaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free