Из Java SE 13 документов , пожалуйста, прочитайте следующую выдержку:
Строковый литерал является ссылкой на экземпляр класса String (§4.3.1 , §4.3.3).
Более того, строковый литерал всегда ссылается на один и тот же экземпляр класса String . Это связано с тем, что строковые литералы - или, в более общем смысле, строки, являющиеся значениями константных выражений (§15.28) - «интернированы», чтобы совместно использовать уникальные экземпляры , используя метод String.intern (§12.5 ).
Строка "interning" в Java хранит объект String в пуле, так что несколько копий строкового литерала в вашем коде ссылаются на один и тот же объект String, а не на несколько одинаковых «Строковые объекты. Возможно, следующий пример прояснит это немного подробнее:
String hello = "Hello"; //A new String object with the value "Hello" is created in the String pool; the variable hello references that object in the pool
System.out.println(hello == "Hello"); //prints true
Так что в вашем случае, даже если вы продолжаете вызывать метод func
миллиардов раз с одним и тем же литералом String, только 1 объект String с значение 'ab c' существует в пуле, и все литералы "ab c" ссылаются на один и тот же объект.
for (long i = Integer.MAX_VALUE; i <= Integer.MAX_VALUE; i++)
func("abc"); //Only 1 String object is created
Однако, если вы явно создаете новые объекты String из литерала, вы можете в конечном итоге в памяти будет несколько объектов String с одним и тем же значением, пока объекты, не находящиеся в контексте, не будут удалены.
for (long i = Integer.MAX_VALUE; i <= Integer.MAX_VALUE; i++)
func(new String("abc")); //multiple String objects with the same value are created and will continue to exist until garbage collected.