3 objects are created here.
The first two objects are obvious:
String s1 = "a"; // First
String s2 = "b"; // Second
The third object is a new object
String s3 = "a" + "b"; // Third
The only relation it has to s1
and s2
is that it contains the same letters as them, but it is a completely independent object. It's basically built like this:
String s3 = new String(s1.toString() + s2.toString());
Even if 2 strings contain the same character sequence they are not the same string.
String s4 = "foo";
String s5 = "foo";
EDIT
s4 == s5; // Evaluates to true
s4.equals(s5); // Evaluates to true
Both of the above will evaluate to true because of string pooling but are still separate objects. They use the flyweight design pattern in order to save memory.
On the other hand:
String s6 = new String("foo");
String s7 = new String("foo");
s6 == s7; // Evaluates to false
s6.equals(s7); // Evaluates to true