Рассмотрим следующий код: String str1 = "Hello";
String str2 = "World";
String str3 = str1 + str2;
String str4 = new String("HelloWorld"); В этом коде будет создано три объекта класса String. Первый объект "Hello" будет создан в момент компиляции кода и будет храниться в пуле строк (string pool) в куче (heap). Второй объект "World" также будет создан в момент компиляции кода и будет храниться в пуле строк в куче. Третий объект str3 будет создан при выполнении операции конкатенации строк (str1 + str2) и будет храниться в куче, но не в пуле строк. Это происходит потому, что результат операции конкатенации строк не может быть предварительно известен в момент компиляции, поэтому его нельзя поместить в пул строк. Четвертый объект str4 будет создан с помощью оператора new и будет храниться в куче как отдельный объект типа String. Поскольку в данном случае был явно вызван конструктор класса String, то объект не будет помещен в пул строк. Таким образом, в данном коде будет создано три объект