<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Pedagogically, it would be nice to have some sugar for .equals()
that makes it remotely close in visual appeal to ==. Ideally it
would be = but that is already ruined. My best alternative
suggestion would be<br>
</p>
<p>e1 .= e2</p>
<p>Cheers,<br>
</p>
<p>-- Andrew<br>
</p>
<div class="moz-cite-prefix">On 10/23/23 10:37 AM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite" cite="mid:2007b791-bdfc-1919-e4a0-854af7eb47fc@oracle.com">
<font size="4"><font face="monospace">One of the pleasant
side-effects of Project Valhalla is that (a) we'll be able to
say .equals() on primitives, and (b) the cost of doing so will
JIT down to that of ==. Which means that we can tell people
"just use .equals() everywhere" (except when implementing
low-level code like IdentityHashMap) and they will never have
to wonder which to use. I realize this doesn't solve the
"wrong op got the good name" problem, but it gives us a path
to not having to think about it so often.</font></font><font size="4"><font face="monospace"><br>
<br>
It may be possible to migrate String to a value class at some
point in the distant future (though this has a considerable
shroud of uncertainty surrounding it), which makes this
problem recede farther into the background for the particular
case of String. Which might be enough to make this
significantly less of a problem, for the reasons you outline
here. <br>
<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 10/23/2023 5:32 AM, Andrew Dinn
wrote:<br>
</div>
<blockquote type="cite" cite="mid:8f1a485b-d6d2-12af-ab14-469e33d7ab0d@redhat.com">Hi
Brian, <br>
<br>
I think there is also another subtle confusion lying behind this
question. Strings are in the unusual position that they can be
named via program literal text e.g. The 7 character sequence
"hello" in a program body is a literal reference to an instance
of java.lang.String. <br>
<br>
That is not the case for any other class of object bar one, the
exception being instances of java.lang.Class e.g. the 22
character sequence java.lang.String.class in a program body
serves as a literal reference to an instance of java.lang.Class.
<br>
<br>
It is easy for a novice programmer to draw the conclusion that
this literal reference must exist 1-1 with regard to its
corresponding literal i.e. that there will only ever be one
String whose ordered sequence of characters will be 'h', 'e',
''l', 'l' and 'o'. The fact that <br>
<br>
new String("hello") == "hello" <br>
<br>
will evaluate to false is not immediately evident to beginner
programmers. <br>
<br>
This misnomer is helped along by the fact that the JVM ensures
that all occurrences of a String literal in disparate class
files do end up referring to the same String instance. If method
m of class C passes the literal String "hello" to method m2 of
class C2 and the latter compares its input to the literal String
"hello" using an equality comparison then the result will be
true. <br>
<br>
class C <br>
{ <br>
. . . <br>
void m() { <br>
C2.m2("foo"); <br>
} <br>
} <br>
<br>
class C2 <br>
{ <br>
. . . <br>
static void m2(String s) { <br>
if (s == "foo") { <br>
System.out.println("identity equal"); <br>
} <br>
} <br>
} <br>
<br>
The message printout will always be triggered. i.e. Strings
mentioned as program literals in source code and thereby
introduced as String constants in bytecode are *deduplicated*
to the same String instance when the bytecode is loaded by the
JVM. <br>
<br>
That is why it takes some work to arrive at a case like the
first code snippet above where two Strings can have equal state
but not equal identity. At least one of the String instances has
to be explicitly created at runtime via new, substring() or some
other method that synthesises a String object. <br>
<br>
It is interesting to compare this situation with that for class
literals where deduplication is either not required or would be
incorrect. It requires a much greater feat of ingenuity
(equally, carelessness or recklessness), involving the use of
application-defined class loaders, to arrive at a situation
where the program literal org.my.Foo.class occurring in a method
m of class C can identify a different instance of
java.lang.Class to the same program literal occurring in a
method m2 of class C2. Yet it is possible: <br>
<br>
class C <br>
{ <br>
. . . <br>
void m() { <br>
C2.m2(org.my.Foo.class); <br>
} <br>
} <br>
<br>
class C2 <br>
{ <br>
. . . <br>
static void m2(Class<?> c) { <br>
if (s != org.my.Foo.class) { <br>
// Yes, if you misbehave you can end up here! <br>
System.out.println("you are in classloader hell!");
<br>
} <br>
} <br>
} <br>
<br>
I guess I could offer instructions as to how to arrive at the
situation where m2 prints out its warning message but I'll leave
that as an exercise for the expert (or unwary) reader. <br>
<br>
regards, <br>
<br>
<br>
Andrew Dinn <br>
----------- <br>
<br>
On 22/10/2023 22:29, Brian Goetz wrote: <br>
<blockquote type="cite">First of all, the question is framed in
a way that assumes its own conclusion; that somehow there is
something "broken" to be "fixed". The == operator on object
references asks a simple, well-defined, fundamental question:
do these two object references _refer to the same object_.
There is a similar, related question of "do these two objects
_encode the same domain value_" (which is inherently
class-specific), and that goes by the name of the "equals"
method. These are two different questions, and it is important
to be able to ask each. One does not replace the other. <br>
<br>
The presumption that something is "broken" comes from the
subjective perception that the "less important" operation got
the "better" name. Indeed, without a clear understanding of
what these two questions are, it is easy to make mistakes.
The comparison to C# illustrates that other languages could
make other choices, which might result in a different category
of mistakes that users might or might not make. <br>
<br>
While the answer you got said "backward compatibility", this
is a too-simplistic (though often repeated) answer; the answer
really is "because this exactly is how the language was
designed to work", which means this is not something to be
"fixed". If we agreed that this original intention was
wrong-headed, then the issue of compatibility would come in --
that there are billions of lines of code that have been
written in Java, and turning Java into Java++, whether
"better" or not, would break many of them. (Sometimes
language do make incompatible changes because something is so
egregiously broken that it is better to break half the world's
code than continue living with it, but the bar for this is
extremely high, and "I wish the other operation got the good
name" doesn't come near it.) <br>
<br>
But the eye-rolling of "how much are we going to sacrifice at
the altar of backward compatibility" is misplaced. The ==
operator on object references still has a clearly defined
meaning, and it is the intended meaning. It may be
unfortunate that the "good" name was taken by the "less
common" operation, but programming languages are full of such
things, and one can easily identify such things in each of the
other 19 languages you list. Ultimately, when there are two
ways to do something (such as identity comparison and state
comparison), someone has to choose which one gets which name,
and sometimes someone doesn't agree with that choice. <br>
<br>
In the future, when Project Valhalla delivers value types,
which are classes whose instances have no object identity, the
== operator will compare these objects by their state, not
their identity (since they have none.) But even this would
not obviate the need for Object::equals, since there are many
classes that are suitable to be value types (such as Rational)
where multiple distinct representations (e.g., 1/2 and 2/4)
are mathematically equal. So even there, we need different
ways to spell "same object" and "equivalent value". <br>
<br>
In the farther future, if Java ever has operator overloading,
one might be able to overload `==`, but being able to do that
brings its own set of problems and confusions. <br>
<br>
Which is to say, there really are two questions here, "same
object" and "domain equivalence", and you need ways to ask
both. <br>
<br>
<br>
<br>
<br>
On 10/22/2023 3:29 PM, David Alayachew wrote: <br>
<blockquote type="cite">Hello, <br>
<br>
Thank you for reaching out! <br>
<br>
I'm pretty sure that the amber-dev mailing list is not the
correct place for this type of question. This topic usually
goes on at the following mailing list instead. I've CC'd it
for you. I would also encourage you to remove amber-dev from
your CC when responding to me, or anyone else on this
thread. <br>
<br>
<a class="moz-txt-link-abbreviated moz-txt-link-freetext" href="mailto:discuss@openjdk.org" moz-do-not-send="true">discuss@openjdk.org</a>
<br>
<br>
To answer your question, this is a very common request, and
the biggest answer is definitely still the backwards
compatibility problem. But tbh, the question I have for you
is this -- is it such a big cost to call the o1.equals(o2)
method instead of using ==? And if you want to handle nulls
too, you can import java.util.Objects (that class is full of
useful static utility methods) and then just say
Objects.equals(o1, o2) instead. I am pretty sure that that
exact method was created in response to your exact question.
<br>
<br>
I understand it might be inconvenient, but making a change
like you suggested would be very disruptive for very little
benefit. All you would gain from doing this would be a
slightly better syntax for representing object equality and
a little more ease when it comes to teaching somebody Java.
Is that really worth the effort? <br>
<br>
As for the class-file api, I'll CC them so that someone can
fact check me. Assuming I'm not wrong (no one responds to
that point specifically), I would also drop that mailing
list from your CC when responding. <br>
<br>
The purpose of the Class-File API was to build and transform
class files. So that seems unrelated to what you want. You
want to repurpose old syntax, but syntax stops being
relevant after compilation, and it is these compiled class
files that the Class-File API deals in. If we tried to use
that API to handle class files created with the old syntax,
then we would have a migration and clarity problem, amongst
much more. <br>
<br>
Let us know if you have any more questions. <br>
<br>
Thank you for your time! <br>
David Alayachew <br>
<br>
<br>
On Sun, Oct 22, 2023 at 2:12 PM tzengshinfu <a class="moz-txt-link-rfc2396E" href="mailto:tzengshinfu@gmail.com" moz-do-not-send="true"><tzengshinfu@gmail.com></a>
wrote: <br>
<br>
Hi, folks: <br>
<br>
When I switched my primary programming language from C#
to Java, I <br>
found myself perplexed by 'string comparison' (and still
do at <br>
times). While string comparisons can sometimes become
quite <br>
intricate, involving issues like case sensitivity,
cultural <br>
nuances... most of the time, all that's needed is
string1 == string2. <br>
<br>
I discovered that a similar question was asked a decade
ago <br>
(<a class="moz-txt-link-freetext" href="https://urldefense.com/v3/__https://www.reddit.com/r/java/comments/1gjwpu/will_the_equals_operator_ever_be_fixed_with/__;!!ACWV5N9M2RV99hQ!NMbrc-pVC7Fix0fznwtzWbOW7c0MPb0ip-0s0pQQTbroMgFLJHOYeM2Ivmn0M7z-TdVpjJXT-JW6WDo$" moz-do-not-send="true">https://urldefense.com/v3/__https://www.reddit.com/r/java/comments/1gjwpu/will_the_equals_operator_ever_be_fixed_with/__;!!ACWV5N9M2RV99hQ!NMbrc-pVC7Fix0fznwtzWbOW7c0MPb0ip-0s0pQQTbroMgFLJHOYeM2Ivmn0M7z-TdVpjJXT-JW6WDo$</a>
), with responses indicating that it's due to 'Backward
compatibility,' and therefore, unlikely to change. (Backward
compatibility! We just keep piling new things on top of
historical baggage, and for users coming from school or from
other languages like C#, Python, C++, Rust, Golang, Kotlin,
Scala, JavaScript, PHP, Rlang, Swift, Ruby, Dart... the top
20 languages according to PYPL, having to consult the
so-called 'Java FAQ' can be frustrating. <br>
<br>
But I believe that if something is amiss, it should be
corrected <br>
to keep moving forward. It would be fantastic if this
issue could <br>
be addressed in a new version of Java and an automatic
conversion <br>
feature provided to fix places in user code that use <br>
String.equals. (Similar to the JVM's preview feature
switch) Is <br>
the Class-File API a potential solution to this problem?
Is my <br>
idea unrealistic? <br>
<br>
/* GET BETTER EVERY DAY */ <br>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
</body>
</html>