Java will intern string constants (final strings) and literals (create one instance of each string in an internal pool) and thus you might get the same instance, even if it is "created" by concatenation.
And as the others already stated, compiler optimization would actually turn the concatenation into one literal ("ab").
You can never fully rely on the ==
semantics of String, that's why you should always use equals(..)
.
Edit: to clarify the above sentence:
With objects ==
always means that the references are compared and it will always return true if both references are the same. However, you can't always rely on getting the same reference of an object (like in your example where a simple final
changes behavior or in frameworks like Hibernate etc.) - that's why you generally should use equals(...)
instead.
Of course you can use ==
if you need physical equality (the very same object) instead of logical equality (the same value).
Another example where ==
would have different results, although from a locical point of view both should be true:
Integer l1 = 0;
Integer l2 = 0;
l1 == l2; //most often true, since Integer objects up to 127 are cached
Integer l1 = 1000;
Integer l2 = 1000;
l1 == l2; //most often false, since those are not cached anymore
Note that with "most often" I mean that this could change between Java versions (if not different JVMs), although that's not very likely.