Constructors and this
In the previous lesson, a point took three lines to assemble: new Point(), then p.x = 3; and p.y = 4;. Forget one of them and the field stays 0, and the compiler says nothing. Ten points would take thirty lines.
Back to the blueprint. A crew builds the house from it: they put up the walls, fit the windows and only then hand over the keys. The new owners get a finished house and build nothing themselves. In a class, the crew's role is played by a constructor, code that runs when each object is created:
public class Main {
public static void main(String[] args) {
Point a = new Point(3, 4);
System.out.println(a.x + " " + a.y); // 3 4
}
}
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}Let's go through the program step by step:
Point(int x, int y)inside the class is a constructor. Its name matches the class name.new Point(3, 4)builds an object and at once calls the constructor with the arguments3and4.this.x = x;andthis.y = y;put these numbers into the fields of the new object.- The reference to the finished point goes into
a, andprintlnprints3 4.
What a constructor is
A constructor looks like a method, but it has its own rules:
- its name matches the class name, down to the capital letter:
Point; - it has no result type, not even
void: withvoidit would be an ordinary method namedPoint; newcalls it, exactly once for each object;- parameters work as in a method: the arguments of
new Point(3, 4)go into them in order.
A constructor may hold any code: check the arguments, print a line. But its main job is to fill in the fields of the new object.
this.x and x
Inside the constructor there are two different x. The first is the parameter: it appears with the call and disappears when the constructor ends. The second is the object's field, which stays with the point. A bare name means the nearest variable, that is, the parameter: it hides the field.
To reach the field, you write this.x. this is a reference to the object being built right now. Each new builds its own object, so each call has its own this too. This gives:
this.xis the fieldxof the new object;xis the parameter, that is, the number from the callnew Point(3, 4).
In the widget, the program builds two points. The frame Point(…) is the running constructor: it shows the parameters x and y and the new object's fields this.x and this.y. Press "Next step" and watch where each number goes.
1public class Main {2 public static void main(String[] args) {3 Point a = new Point(3, 4);4 Point b = new Point(5, 6);5 System.out.println(a.x + " " + a.y);6 System.out.println(b.x + " " + b.y);7 }8}9 10class Point {11 int x;12 int y;13 Point(int x, int y) {14 this.x = x;15 this.y = y;16 }17}
new Point(3, 4) builds an object whose fields x and y are 0 and calls the constructor.
When the constructor ends, this and the parameters disappear along with its frame, but the object stays, and the reference to it goes into a or b. The line this.x = x in the second call does not touch the first point: the second call has its own this.
Here the crew picture is not exact. A real crew starts from an empty lot, while a constructor gets an object that is already built. The JVM creates it with default field values, 0 for x and y, and only then runs the constructor.
The default constructor
How did new Point() work, then, in a class that had no constructor at all? If a class has no constructor, Java adds an empty one itself, with no parameters. This is the default constructor. But once you write your own, Java no longer adds it:
Point a = new Point(3, 4);
Point b = new Point(); // ✗error: constructor Point in class Point cannot be applied to given types;The program does not compile. The class has one constructor left, and it expects two int values. Java does not fill in missing arguments and does not look for an empty constructor. The call must match one of the written constructors in the number and types of its arguments. The compiler checks this, before the program runs.
Interviewers like to ask this: when does a class have a default constructor? Only when you have not written one of your own.
Calling this(…)
To make new Point() work again, you write the constructor without parameters yourself. A class may have several constructors, like an overloaded method, as long as their parameters differ:
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
Point() {
this(0, 0);
}
}The call this(0, 0) runs another constructor of the same class, the one that takes two int values. One constructor fills in the fields, and the others hand the work over to it. If a check is later added to the main constructor, it will run whichever way a point is created.
The call this(…) goes on the first line of the constructor. Java 21 allows no other order, while Java 25 allows some statements before it, such as checking the arguments. The course writes code so that it also compiles on Java 21.
Common mistake
this is missing before one of the fields:
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
y = y; // ✗
}
}The program compiles, but new Point(3, 4) gives the point 3 0. The line y = y puts the parameter y into itself, and the field y stays 0. The compiler gives no warning about it. Write this. before every field that has a parameter with the same name: this.y = y;.
Key points
- A constructor is named after its class and has no result type;
newcalls it for each new object. - Inside a constructor,
this.xis the new object's field andxis the parameter;y = ywithoutthisdoes not change the field. - Java adds a default constructor only if the class has no constructor of its own.
this(…)on the first line of a constructor calls another constructor of the same class.