Have you already once asked yourself, what’s the difference between equals(..) and the == operator? It’s simple to explain it, but side-effects of this purpose can be enormous.
x.equals(y) checks, if the values of instance x are equal to the values of instance y. You can override equals() and define by yourself, which properties should be compared.
The == operator checks if two instances are the same. That means, they are stored at the same address in memory.
My Side-Effect Experience:
I tried to compare two int variables with ==. That worked well for small numbers, but wasn’t correct for large ones. I tried to debug it and found out, that the magical barrier lied at 127 for which the == comparison worked. I asked my prof and he said that Java had an internal lookup table for integers to speed up operations. That means, the Java Virtual Machine instantiates every instance of the integers between 0 and 127 at startup. Later Java just uses pointers to reference to these numbers. Values greater than 127 are really instantiated and therefore the == comparison doesn’t work as expected on them.