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
Dogfor the classDog; - 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:
- Add the constructor inside
Dog, below the fields, with the signaturepublic Dog(String name, int age). Usethis.nameandthis.ageon the left of each assignment. - Create the dogs in
mainFunctionwithnew Dog("Rex", 4)andnew 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 namedDog, andnew 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 asdogName, also avoids the problem. - Swapping arguments.
new Dog(4, "Rex")doesn't compile, because anintis not aString. 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
newcreates 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(...).