I am studding and preparing for OCP 1Z0-815 and I read from this excellent preparing book:
Deshmukh, Hanumant. OCP Oracle Certified Professional Java SE 11 Programmer I Exam Fundamentals 1Z0-815: Study guide for passing the OCP Java 11 Developer Certification Part 1 Exam 1Z0-815 (p. 99). Enthuware. Edição do Kindle.
String str = "hello"; for( int i = 0; i < 5; i + +) { str = str + i; }
The above creates one String object containing "hello" at the beginning and then two more in each iteration of the loop - a String containing the int value of i and the concatenated String. Thus, overall, the above code creates 1 + 2* 5 = 11 Strings. However, if you are asked how many String will be eligible to be garbage collected, the answer is not that easy. The Java Language Specification mentions in Section 15.8.1 that the non-string operand of the + operator is converted to a String at runtime but it does not clearly tell whether this String goes to the String pool (in which case it will not be garbage collected) or not.
Let me show you another piece of code:
String s = "hello"; int k = 100; s = s + " 123" + k;
In this case, JLS section 15.8.1 clearly says that a compiler may avoid creating multiple strings altogether by making use of a StringBuilder. Thus, it is not possible to tell how many Strings will be created and how many will be eligible to be garbage collected...
The statement above "...The Java Language Specification mentions in Section 15.8.1 that the non-string operand of the + operator is converted to a String at runtime but it does not clearly tell whether this String goes to the String pool..." drove me to search around but I didn't manage to find an explanation: as far as I don't see "new" I understand that indeed it goes to String pool and so it is not an object. Consequentlly it is not elegiable for garbage collection at all. Am I saying something wrong?
In other words, as far as understand, every loop will result in a constant string in String Pool in Heap (Java 11 in mind instead of Java 7). hello0, hello1, hello2 and so on and there will not be any candidate for Garbage Collection at all. I understand that Garbage Colletion "clean" objects created by new operator and doesn't act on String Pool.
Based on conclusion paragraph, "... section 15.8.1 clearly says that a compiler may avoid creating multiple strings altogether by making use of a StringBuilder. Thus, it is not possible to tell how many Strings will be created and how many will be eligible to be garbage collected..." I assume it is saying that I can't discover how many Strings are created in String Pool in second code example (wihtout loop) because StringBuilder is used behind the scene and we know that StringBuilder manipulate concatenation in memory avoiding creating many String literals. Well, if that is the case, I still can assume in first code thatt fofr each loop will result in a Literal String (hello0, hello1...) that goes to String Pool and will not be eligible for Garbage Collection in pratical terms. Am I wrong?
PS.: You may comment that Garbage Collection acts on String Pool but I understand that in pratical terms, literal string in String Pool resides for a so long time that we can consider it is never eligible for Garbage Collection before program ends (" there is an implicit reference to the String object in the code of every method that uses the literal." and " all string literals in the string pool are reachable until the program is terminated and thus not eligible for garbage collection"