← Назад к вопросам

Куда отправится строка при использовании 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 (одинаковый контент)

Когда это важно знать?

  1. Performance — избегать ненужного new String()
  2. Memory Leaks — большие строки в Heap могут засорить память
  3. == vs equals() — понимать разницу сравнений
  4. Interview — это классический вопрос на знание Java

Вывод: При использовании new String(), строка создаётся в Heap, а не в String Literal Pool. Это менее эффективно, чем использование литератора, и редко используется на практике.

Куда отправится строка при использовании new String? | PrepBro