if (str1 == str2) {
// oops
} if (str1 == str2) {
// oops
}There's a reason newer JVM languages like Kotlin use == as an alias for equals instead of reference equality.
Sometimes, it happens in core Java libraries themselves: https://bugs.openjdk.java.net/browse/JDK-8274779
https://github.com/openjdk/jdk/blob/722d639fad2e4fc6eb2aabd4...
Curiously, I don't do a lot of value-comparisons. Based on grepping in the repo for my search engine, I appear to do one every 1000 lines of code. May just be how I write code though. Some people seem to do that a lot more.
edit:
Kotlin uses `===`, which is another good option.
Look, languages are moving away from permitting constructs like "if (x = 1)" because it's difficult to distinguish from "if (x == 1)". Adding "if (x === 1)" into the mix is arguably a step backwards in terms of clarity.
The tricky one is numbers.
Integer == int // fine
int == int // fine
numVarOne == numVarTwo // Uh-oh
In that third example you better make sure they aren’t both boxed objects or BigDecimals.
I’ve almost never seen the string one for some reason. It’s always boxed numbers.
Again, a good IDE is worth a ton.
The good news is that a linter trivially detects this bug.
I mean by that same logic, Javascript will confuse you as well because `{} != {}`, or C++ because of pointer mechanisms and custom operators.
Boolean.getBoolean, however, now that is a proper Java land mine.
Though I’m not sure why wasn’t two new i’s added instead of modifying the latin i? It is a different letter after all in this case.
This is consistent with the rest of the language, but I'd bet one rarely wants referential equality when comparing strings.
People commenting "yeah but that's because you are a newbie / you are comparing references and you should know better" miss the point I think. I can easily see myself making this mistake while fully understanding what's going on.
Basically the tooling around Java is very evolved and Java static type system helps the IDEs a lot. One of the main reason enterprises prefer Java. Also majority of the tools and IDEs is free for commercial use.
We are expected to learn about our tools.
I hope making mistakes is ok though?
I learnt C years before Java, it's also the first language I properly learnt. And a little bit of C++ too, so I've known the concepts of pointers and references way before learning Java. In C, you also either do pointer equality or explicit value equality (with strcmp) for string equality tests. I never had any issue understanding how things work in Java. It's not about learning anything. It's about doing mistakes. And I won't take "you should know better" as a counter argument to a mention of some rough edge in an API or a programming language. It's like Javascript: you might know the differences between == and === in Javascript full well, but still happen to write == by mistake because you just wrote some C/Java/Python code just before. I'll probably not forget about .equals(...) in Java most of the time but the fact that == would be silently accepted and not do what is wanted is still a bit concerning (and .equals(...) is ugly, too).
A linter will do indeed and that's a fair point. I'd argue that linters are there to work around rough edges of programming languages, but that's fair enough too, every programming language has its gotchas and I'll accept considering a programming language + its linter(s) instead of a programming language alone. However, that's still not ideal because you might have to work on non linted code and deal with these gotchas without any safety net.
I hadn't thought about number comparisons (mentioned in other comments) but that's even worse indeed.
It's no wonder Kotlin and Groovy both chose value comparison for ==.