Implementation of == and Object::equals

John Bossons jbossons at gmail.com
Tue Apr 9 13:01:47 UTC 2024


Thanks, Remi. Very interesting, more than answers my question!

John

On Tue, Apr 9, 2024 at 7:09 AM Remi Forax <forax at univ-mlv.fr> wrote:

>
>
> ------------------------------
>
> *From: *"John Bossons" <jbossons at gmail.com>
> *To: *"valhalla-dev" <valhalla-dev at openjdk.org>
> *Sent: *Monday, April 8, 2024 4:30:44 AM
> *Subject: *Implementation of == and Object::equals
>
>
> Hi John,
> adding to what Roger said,
>
>
> I'm not sure that this is the right place to raise this, but don't know
> where else to do so.
> For identity types, == is simply a test of reference equality and so is a
> useful first test in an overriding type-specific equals method.
>
>
> No, it's a bad idea performance-wise.
> see https://youtu.be/kuzjX_efuDs?list=PLX8CzqL3ArzV4BpOzLanxd4bZr46x5e87
>
>
> For value types, the relationship is more subtle, since == is a test of
> value equality, not reference equality. I suggest it be implemented as an
> operator causing Object::equals to be invoked, so that if Object::equals is
> overloaded (e.g. to first test equality of hash codes or otherwise modify
> the default equals test), the overloaded method is automatically invoked
> when == is used.
>
> This would mean that Object::equals implements the == operator, rather
> than the reverse, so that a specification that a == b always means
> a.equals(b), whether implemented by the default test or by an overriding
> type-specific method (that e.g. tests for equality of identity object field
> values). I believe this would make value types (especially value trees)
> easier to use.
>
>
> Two things, (1) the semantics of equals() on a class (value or identity)
> is stronger than the semantics of == on a value class, (2) what you propose
> introduce a circularity between == and equals, so if equals itslef uses ==,
> it's an infinite loop.
>
> Imagine you have a value class defined like this:
>   value class MyValueClass {
>     String s;
>
>     public boolean equals(Object o) {
>       return o instanceof MyValueClass other && s.equals(other.s);
>     }
>   }
>
> 1) calling == on an instance of MyValueClass should check if s == other.s,
> not calling s.equals(other.s) on the field "field" so the semantics of ==
> is different from the semantics of equals.
>
> 2) if we write equals like that and == calls equals()
>
>    public boolean equals(Object o) {
>       return this == o && o instanceof MyValueClass v &&
> field.equals(v.field);
>     }
>
> we have an infinite loop.
>
> That's why == on value type is defined as doing == on each field and not
> as calling equals on each field.
>
> That's said, in the future, for some value types, we may let users to be
> able to override == and identity hashCode so anyone can write it's own
> primitive type, but it will not be the default behavior and we are not
> there yet.
>
>
> John
>
>
> regards,
> Rémi
>
>
> --
> Phone:  (416) 450-3584 (cell)
>
>

-- 
Phone:  (416) 450-3584 (cell)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20240409/ae2bf3e8/attachment.htm>


More information about the valhalla-dev mailing list