☰ Contents Java Details

Records Under (or Over) Construction

Student: I noticed that both new Circle(5, "red") and new Circle(5, Color.RED) work. Does that mean you can overload constructors, and how does that work?
Prof: Yes, you can! Imagine we wanted a helpful constructor for a RectangleRegion, which has a corner point, a width and a height. The constructor just takes a width and a height, and always puts the corner at 0, 0:
Prof: You can see that r2 has the Point[x=0.0, y=0.0] – that was created in the constructor. What else do you notice about the syntax here?
Student: Well, it uses this with parentheses after it.
Prof: Right! So inside a constructor, this(...) means to call another constructor. In this case we’re calling the one Java wrote for the record (the one that takes a Point and two double values) from the one that takes just the two double arguments.
Student: Interesting! So does this with the parentheses work everywhere?
Prof: No it’s super specific – this(...) is actually only allowed inside constructors, and it always means to call another constructor!
Student: Huh. Oh and so what is a constructor?
Prof: Great question. A constructor is code that gets called when you use new on a record (or class) name. The constructor definition looks like a method definition, but instead of a separate return type and method name, it just has the class or record name.
Student: Oh so that’s why it looks weird – RectangleRegion on its own looks like a return type of a method, but there’s no name for it.
Prof: Exactly right – that’s the special syntax of a constructor definition. It is kind of like a method – it gets called on a new object and helps create it. In a record definition, there’s one that Java writes for the record (also called the canonical constructor) that sets the field values.
Student: And that’s how Circle works?
Prof: That’s right. There are several constructors in Circle:
record Circle(int radius, Color color) implements Pict {
    // ...
    Circle(int radius, String color) { this(radius, Colors.named(color)); }
    Circle(double radius, String color) { this(Px.of(radius), Colors.named(color)); }
    // ...
}

Pict.java, lines 142–152

Student: Huh, so that’s what’s been running all along? Wait whats Px.of and Colors.named?
Prof: Great questions, we’ll get there! I’ll give a short answer now: Px.of is a method to turn double values in to specific pixel sizes – the Pict library assumes all sizes are in round pixel amounts. And Colors.named is a method that takes a friendly string name like "red" and produces Color.RED. They are more conveniences!
Student: OK, I can sort of see it. I’ll wait for more.

Practice

Here RectangleRegion has two more constructors. Each one calls another with this(...).

record RectangleRegion(Point p, double w, double h) {
  RectangleRegion(double w, double h) { this(new Point(0, 0), w, h); }
  RectangleRegion(double side) { this(new Point(0, 0), side, side); }
  RectangleRegion(Point p, double side) { this(p, side, side); }
}
What does each one make?
new RectangleRegion(3.0) makes
new RectangleRegion(3.0, 4.0) makes
new RectangleRegion(new Point(1, 1), 2.0) makes
new RectangleRegion(new Point(1, 1), 2.0, 3.0) makes
new RectangleRegion(3) makes