← Назад к вопросам
Куда отправится строка при использовании new String?
2.0 Middle🔥 201 комментариев
#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Куда отправится строка при использовании new String?
Это вопрос о управлении памятью в Java и разнице между String Literal Pool и Heap.
Две разные ситуации
Вариант 1: String Literal (без new)
String s1 = "Hello"; // String Literal
String s2 = "Hello"; // Ссылается на ТОГО ЖЕ объекта в пуле
s1 == s2; // true! Они ссылаются на один объект
Куда отправится? → String Literal Pool (часть Heap, но специальная область)
Вариант 2: String с new (вопрос из интервью)
String s1 = new String("Hello"); // Явное создание нового объекта
String s2 = new String("Hello"); // Ещё один новый объект
s1 == s2; // false! Разные объекты
s1.equals(s2); // true! Но контент одинаковый
Куда отправится? → Heap (не в String Pool)
Память в Java
┌─────────────────────────────────────┐
│ JVM Memory │
├─────────────────────────────────────┤
│ │
│ ┌─────────────────────────────┐ │
│ │ Heap (Объекты, массивы) │ │
│ │ ┌─────────────────────────┐│ │
│ │ │ String Literal Pool ││ │
│ │ │ ("Hello", "World", ...) ││ │
│ │ └─────────────────────────┘│ │
│ │ │ │
│ │ new String("Hello") → сюда │ │
│ │ │ │
│ └─────────────────────────────┘ │
│ │
│ Stack (примитивы, ссылки) │
│ │
└─────────────────────────────────────┘
Практический пример
public class StringMemory {
public static void main(String[] args) {
// 1. String Literal → String Literal Pool
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // true (один объект)
// 2. new String → Heap, а не Pool
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println(s3 == s4); // false (разные объекты)
System.out.println(s3.equals(s4)); // true (одинаковый контент)
// 3. Интересный момент: новый объект, но синтаксис литерала
String s5 = new String("Hello");
String s6 = "Hello";
System.out.println(s5 == s6); // false (разные объекты)
// s5 создан в Heap
// s6 ссылается на Pool
}
}
Почему это происходит?
String Literal Pool — это оптимизация для:
- Экономии памяти (одинаковые строки != разные объекты)
- Быстрого сравнения (== вместо equals())
- Производительности приложения
// Оптимизация работает так:
String a = "Java"; // Создаёт в Pool
String b = "Java"; // Повторно использует из Pool
String c = "Java"; // Повторно использует из Pool
// В памяти всего 1 объект "Java"
// С new это не работает:
String x = new String("Java"); // Новый объект в Heap
String y = new String("Java"); // Ещё один новый объект
String z = new String("Java"); // Ещё один новый объект
// В памяти 3 разных объекта с одинаковым контентом
Как это выглядит визуально
// Скрипт создания объектов
String s1 = "Hello"; // Pool
String s2 = new String("Hello"); // Heap
// Память (визуализация)
┌─────────────────────────────┐
│ String Literal Pool │
│ "Hello" ← s1 ──────────────┐│
│ ││
└─────────────────────────────┘
┌─────────────────────────────┐
│ Heap (Regular Objects) │
│ String Object ← s2 ─────────┐│
│ "Hello" ││
│ ││
└─────────────────────────────┘
s1 == s2? → false (разные объекты)
Когда new String используется?
Редко, потому что неэффективно:
// ❌ ЭТО ПЛОХО
String s = new String("Important data"); // Зачем создавать два объекта?
// Происходит:
// 1. JVM создаёт "Important data" в String Pool
// 2. Затем new String() создаёт копию в Heap
// 3. s ссылается на копию в Heap
// ✅ ЭТО ХОРОШО
String s = "Important data"; // Просто используем из Pool
Исключение: когда нужна независимая копия
// Когда может быть полезно new String():
char[] charArray = {'J', 'a', 'v', 'a'};
String s = new String(charArray); // Создаём String из массива
// Или когда работаем с байтами
byte[] bytes = "Hello".getBytes(StandardCharsets.UTF_8);
String s = new String(bytes); // Конвертируем байты в String
String.intern() — обратная операция
// intern() помещает строку в Pool
String s1 = new String("Java"); // Heap
String s2 = s1.intern(); // Pool
String s3 = "Java"; // Pool
s2 == s3; // true! Теперь оба в Pool
Производительность
Создание String в цикле — проблема:
// ❌ Создаёт новый объект каждый раз
for (int i = 0; i < 1_000_000; i++) {
String s = new String("Result"); // 1 миллион объектов в Heap!
}
// ✅ Переиспользует из Pool
for (int i = 0; i < 1_000_000; i++) {
String s = "Result"; // 1 объект в Pool
}
Ответ на вопрос интервью
"Куда отправится строка при использовании new String?"
Ответ:
В HEAP (обычную область памяти для объектов).
Визуально:
new String("Hello")
↓
Создаёт новый объект в Heap,
(не в String Literal Pool)
Дополнение:
- String Literal (без new) → String Pool
- new String() → Heap
- Они хранятся в разных местах памяти
- == сравнение будет false (разные объекты)
- .equals() сравнение будет true (одинаковый контент)
Когда это важно знать?
- Performance — избегать ненужного new String()
- Memory Leaks — большие строки в Heap могут засорить память
- == vs equals() — понимать разницу сравнений
- Interview — это классический вопрос на знание Java
Вывод: При использовании new String(), строка создаётся в Heap, а не в String Literal Pool. Это менее эффективно, чем использование литератора, и редко используется на практике.