Let's look step-by-step:
String s1 = "cat";
String s2 = "cat";
These two will be just the same constant pool entry created in your class file by javac compiler. When this class is loaded, this string (along with all other constant pool strings) will be automatically interned, thus it will be also merged with other "cat"
strings in other classes.
String s3 = "c"+"at";
This is practically the same: if string concatenation can be computed during the compilation, it's done by javac. So it's practically the same as s1
and s2
. This is covered by JLS, chapter 15.18.1:
The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).
String s4 = new String("cat");
Here you explicitly create a new object. Java language guarantees that when you use a new
keyword, you will have a new distinct object which cannot be the same as any of objects created previously. However if you use this object only in current methods (or in methods which can be inlined into the current) and don't use ==
operation to compare it with other strings, JIT compiler can skip the object allocation for optimization. But if you actually use ==
or System.identityHashCode
, or this method is executed as interpreted frame, then it will be actually new object.
The "cat"
string which is passed to the parameter is actually the same object as s1
, s2
, and s3
.
String s5 = "kitty"+"cat";
This is similar to s3
: the javac compiler will just create a "kittycat"
string during the compilation. Looking into bytecode you cannot even know that there was a concatenation in the source.
String s6 = new String("kittycat");
This is similar to s4
: new object is created explicitly. If you try to use s6 == "kittycat"
later, you will get false
.
String s7 = s5;
Here you just assign a reference to the previously created s5
string, thus no new object is created here.
So the answer is: at most 4 strings will be created, but in some cases it can be optimized down to 2 strings. And the most important: if you try to check how many strings you have from inside the same program (i.e. not using Java agent or analysing memory dump), you will always get four.