Records (preview): Why aren't accessor methods generated as final?
Jonas Konrad
me at yawk.at
Fri Apr 24 21:34:09 UTC 2020
FYI, this is called an "explicit declaration" in the JEP:
https://openjdk.java.net/jeps/359#Explicitly-declaring-members-of-a-record
- it's not really related to final, because the explicit declaration
happens in the same class, not a different one.
The javadoc of Record also gives one possible use case for explicit
accessor declarations: Defensive copying of mutable members. Maybe
someone else can name more.
Your example fails the copy invariant of Record. Sure, you can do it,
just like you can implement a misbehaving .equals method, but behavior
may be unpredictable.
- Jonas
On 4/24/20 11:04 PM, Mike Bishop wrote:
> I'm curious as to why the accessor methods in a record are not final.
> Consider the following record declaration:
>
> public record Point(double x, double y) {}
>
> The accessor methods x() and y() return x and y, respectively, but are not
> final. This allows me to override x(), for example, as follows:
>
> public record Point(double x, double y) {
> public double x() {
> return x * x;
> }
> }
>
> I can test the above Point record with the following code to ensure that
> two Points with the same declared x and y coordinates are equal.
>
> public static void main(String[] args) {
> var p = new Point(3.0, 4.0);
> var pPrime = new Point(p.x(), p.y());
> System.out.println("p = " + p + ", pPrime = " + pPrime);
> assert pPrime.equals(p);
> }
>
> As expected, the assertion fails as pPrime is (9.0, 4.0) while p is (3.0,
> 4.0).
>
> My concern is that if I'm using a Point in my code, I would expect that two
> Points with the same x and y will be equivalent since the 2-tuple (x, y)
> represents "the state, the whole state and nothing but the state" of Point.
> I think this can only be assured if the accessor methods are final.
>
> Best regards,
> Mike Bishop
>
More information about the amber-dev
mailing list