4 ms·
Even if `record` is a syntactic sugar, I'd better see a canonical constructor added to all usual classes. The constructor parameters are of types of all the fie
by avodonosov 6y ago
Even if `record` is a syntactic sugar, I'd better see a canonical constructor added to all usual classes. The constructor parameters are of types of all the fields, in the declaration order. In this case we could say
class Point { public final int x, y; }
instead of
record Point(int x, int y) { }
Usual non-record classes would benefit greatly from such a feature too.
Actually, if class fields have different visibility, several canonical constructors are needed. If public fields exist, a constructor that sets all public fields. If protected fields exist, a constructor that sets all public and protected fields. If package-private fields exist - setting all public, protected, and package-private fields. If private fields exist - setting all public, protected, package-private, and private fields.
What remains, is value-oriented versions of equals(), hashCode() and toString() to be defined. Probably better to express as a base class than the new keyword `record`;
class Point extends Record { public final int x, y; }
A polyfill for such a base class for older Java:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
class Record {
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, true);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj, true);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
I practice such classes in my code, for constructors, I just don't bother for final (Java does not support it well anyways), and have factory methods in a separate class, so they are out of the readers view.
- papercrane 6y agoAdding a new canonical constructor to all classes would very likely have backwards compatibility issues, so we'd likely need some sort of opt-in mechanism. In the end the language designers decided that they wanted to give developers a way to create a very focused kind of object. This goes into the design motivations: https://cr.openjdk.java.net/~briangoetz/amber/datum.html https://cr.openjdk.java.net/~briangoetz/amber/datum.html Additionally, one less talked about benefit of records is they have a simplified serialization scheme that is safer by default. Records when being deserialized have each of their members read and then the canonical constructor is called, if the values are not valid then the constructor can reject the fields instead of allowing an "impossible" object from being created.
- avodonosov 6y agoThe opt-in (or rather opt-out) could be a presence of user-defined constructor. The same way as with default no-arg constructor. Interesting note about serialization. That could also be part of the base class.