The frustration I have with Records is there is no good way to prevent direct construction of them. That is, the constructor is public, which prevents an easy way of enforcing an invariant during construction.
For example, let's say that you have a record with a Date type. There's no good way to prevent a user from creating the record with an invalid date, one that is out of a needed date range. Or maybe enforcing a field cannot be null or some combination of fields must meet requirements as a group.
The benefit I get from the classic Builder pattern is defeated with Records. I can't enforce checking of my fields before the construction of the record object itself. Presumably I would need to verify the object after construction, which is unfortunate.
record Point(int x, int y) {
Point {
if (x < 0) throw new IllegalArgumentException()
}
}
or if you want to assert something is not null: record Person(String name) {
Person {
requireNonNull(name);
}
}(I know very little about Java)
That is factually incorrect.
You can do all of that validation in a record constructor, much like in a normal Java class constructor. There's a difference in syntax: you don't need to repeat the constructor arguments in parantheses, and don't have to perform the assignments yourself. These are tailored specifically for easy validation.
~Unfortunately, I believe they're mutable (and cannot be made immutable).~ Edit: I was wrong, they're immutable.
[0]: I'm using "object" to mean "data bound to methods", since the concept of aggregate data in general long pre-date OOP (eg, C's structs)
[1]: https://docs.oracle.com/en/java/javase/17/language/records.h...