<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"John Bossons" <jbossons@gmail.com><br><b>To: </b>"valhalla-dev" <valhalla-dev@openjdk.org><br><b>Sent: </b>Monday, April 8, 2024 4:30:44 AM<br><b>Subject: </b>Implementation of == and Object::equals</blockquote><div><br></div><div>Hi John,<br data-mce-bogus="1"></div><div>adding to what Roger said,<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr">I'm not sure that this is the right place to raise this, but don't know where else to do so.<br><div>For identity types, == is simply a test of reference equality and so is a useful first test in an overriding type-specific equals method. </div></div></blockquote><div><br></div><div>No, it's a bad idea performance-wise.<br data-mce-bogus="1"></div><div>see https://youtu.be/kuzjX_efuDs?list=PLX8CzqL3ArzV4BpOzLanxd4bZr46x5e87<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr"><br><div>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.</div><br><div>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.</div></div></blockquote><div><br></div><div>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.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Imagine you have a value class defined like this:<br data-mce-bogus="1"></div><div> value class MyValueClass {<br data-mce-bogus="1"></div><div> String s;<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div> public boolean equals(Object o) {<br data-mce-bogus="1"></div><div> return o instanceof MyValueClass other && s.equals(other.s);<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div> }<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>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.</div><div><br data-mce-bogus="1"></div><div>2) if we write equals like that and == calls equals()<br data-mce-bogus="1"></div><div> <div> public boolean equals(Object o) {</div><div> return this == o && o instanceof MyValueClass v && field.equals(v.field);</div><div> }</div><br data-mce-bogus="1"></div><div>we have an infinite loop.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>That's why == on value type is defined as doing == on each field and not as calling equals on each field.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>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.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr"><br><div>John</div></div></blockquote><div><br></div><div>regards,<br data-mce-bogus="1"></div><div>RĂ©mi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr"><div><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">Phone: (416) 450-3584 (cell)</div></div></div></div><br></blockquote></div></div></body></html>