Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yes, and this is entirely consistent with the overall design of the language. The ‘==‘ does not have a special overload for String instances, which are reference types just like any other in the JVM. The equals operator does a reference comparison, just as it should. If you want to do a logical comparison of instances, you use the equals() method just as you would for anything else.

Frankly, if this is the most meaningful complaint you can come up with, it might be indicative that you haven’t learned enough about it to have an informed opinion.



> The ‘==‘ does not have a special overload for String instances

As a non-Java developer I have to ask why you think this is a reasonable design choice. It's a massive footgun for the a casual polyglot Java developer. I can imagine just forgetting I can't do == if I've just switched from being immersed in another language.


It’s precisely the same behavior you would get with C, C++, C# for references, with C# defaulting the ‘==‘ operator to short-circuit to ReferenceEquals() unless otherwise re-defined.


> with C# defaulting the ‘==‘ operator

Which is surely the important bit. I can just use "==" in C#.


They have a magic overload for '+'. Consistency wasn't much of a priority.


It isn't at all consistent, because integer types compare correctly with == and do not have a .equals() method. And regardless of consistency, if it's a mistake people make frequently with the language and need to learn not to do the obvious thing, it's probably not an ideal bit of design.


In java (and every other C derived language that I know of) there’s a hard and explicit distinction between reference and primitive types.

In fact, from a certain perspective the two flavors get treated identically. Comparing two integers with ‘==‘ will be true if the contents of the variables are the same, and comparing two references will be true if the pointers they contain are the same value. It just so happens that for primitives identity and logical equality are the same thing.


C, C++, Rust, Go, etc have no special distinction between reference types and primitive types but rather everything is a value and some values are pointers/references. In a language with operator overloading, I don’t see why you’d ever want to check string identity by default. Interestingly, Go doesn’t have operator overloading but it treats strings as a special case including doing a string comparison for ==. Not saying this is better or worse, although no one makes mistakes with string comparison as far as I’m aware, for whatever that is worth.


That special case isn't specifically for strings - you can also compare arrays, channels and structs that way (as long as the array/struct doesn't contain anything non-comparable). Unfortunately it's a rarer footgun though since it can panic when comparing interfaces :(


The distinction between String and int in Java is not explicit, certainly not to a beginner; maybe other classes are because you have to create them with new, but it's not obvious that string literals result in a different kind of thing with different rules than integer literals.

Regardless, none of that changes the fact that it's a bad design decision, because people regularly get it wrong.


The flaw in Java design is that String is a reference type. Logically, it's a value, and should be treated as such (and not copying the underlying data should be an implementation detail).

The problem is that in Java, there are no user-defined value types, only primitives; and primitives can't have methods. So if it were a primitive, you'd have to write "String.length(s)" etc. Also, all other Java primitives are basically bit sequences that are interpreted in one way or another, but that wouldn't be the case for strings.

.NET/C#, though, doesn't get that excuse. It totally could have defined String as a struct with an internal char[] field, and then there would be no question of value/reference equality for its ==. But that would also mean that you couldn't use null for strings - and they didn't have nullable value types back then. I suspect that, plus the overall mindset carried over from Java, is what won the day.

Side note: there's no hard and explicit distinction between reference and primitive types in C itself, nor in C++. If Python is "everything is an object reference", and Java is "everything is an object reference except for primitives that are values", then C++ is "everything is a value, including object references". Thus, there's no ambiguity with == in C++ - it always compares values, it's just that sometimes those values are pointers.

I think sometimes that perhaps the implicitness of object references that is so common to OO languages, that I think was introduced by Smalltalk, is a mistake. It's interesting that Simula-67 didn't have it - although it was very Java-like otherwise, having only primitive values and references to objects (i.e. no objects as values, like C++), it distinguished the two consistently by using distinct equality operators (= vs ==), and even distinct assignments (:= vs :-).

Or, alternatively, treat everything as an object reference, but make == do implicit dereferencing as well, as Python and VB do; and provide a completely distinct operator for reference equality, such as "is". Python has a problem in that regard in that it has a default implementation of == for all classes that compares references, and so it ends up used as reference equality in practice sometimes. It would be better to have no default for == at all, just as there's no default for other comparison operators; this is what VB does.

It might also be best to stop talking about value and reference types altogether - what's actually important is the presence or absence of identity. Then everything can be an object reference, but not all object references can be compared for equality (and in practice, under the hood, the implementation can just skip the references and copy the data itself - or not, depending on mutability and size).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: