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

В чем разница между написанием строк в "" и вызовом new String?

2.2 Middle🔥 211 комментариев
#REST API и микросервисы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между литералами строк и new String

Это фундаментальное различие в том, как Java управляет строками в памяти. Важно понимать это для оптимизации и для экзаменов.

Строковый литерал ("")

Когда ты пишешь строку в кавычках, Java помещает ее в String Pool — специальную область памяти для оптимизации.

String str1 = "Hello";
String str2 = "Hello";
String str3 = "Hello";

// Все три переменные указывают на ОДИН объект в памяти!
// str1 == str2 == str3 -> true (одна ссылка)
system.out.println(str1 == str2);  // true
system.out.println(str1.equals(str2));  // true

Как работает String Pool:

// Первый раз видим "Hello" - создается объект в String Pool
String s1 = "Hello";

// Второй раз видим "Hello" - Java переиспользует существующий объект из Pool
String s2 = "Hello";

// s1 и s2 указывают на ОДИН И ТОТ ЖЕ объект в памяти
System.out.println(s1 == s2);  // true (сравнивает ссылки)
System.out.println(s1.equals(s2));  // true (сравнивает содержимое)

Плюсы:

  • Экономия памяти — одна строка хранится один раз
  • Быстрее — нет необходимости создавать новые объекты

new String()

Когда ты используешь new String(), Java ВСЕГДА создает новый объект в кучи (heap), даже если такая строка уже есть в String Pool.

String str1 = new String("Hello");
String str2 = new String("Hello");
String str3 = "Hello";

// str1 и str2 - разные объекты в памяти!
System.out.println(str1 == str2);  // false (разные ссылки)
System.out.println(str1.equals(str2));  // true (одинаковое содержимое)

// str1 и str3 тоже разные объекты
System.out.println(str1 == str3);  // false
System.out.println(str1.equals(str3));  // true

Как это работает в памяти:

String Pool (Memory: PermGen/Metaspace):
┌──────────────────┐
│ "Hello" ← str3   │
└──────────────────┘

Heap (Memory):
┌──────────────────┐
│ "Hello" ← str1   │
└──────────────────┘
┌──────────────────┐
│ "Hello" ← str2   │
└──────────────────┘

Минусы:

  • Расходует память — создаются новые объекты
  • Медленнее — требует создания новых объектов

Практический пример

public class StringComparison {
    public static void main(String[] args) {
        // Литеральные строки - используют String Pool
        String literal1 = "Java";
        String literal2 = "Java";
        
        // new String - всегда новые объекты
        String newStr1 = new String("Java");
        String newStr2 = new String("Java");
        
        System.out.println("literal1 == literal2: " + (literal1 == literal2));  // true
        System.out.println("newStr1 == newStr2: " + (newStr1 == newStr2));      // false
        System.out.println("literal1 == newStr1: " + (literal1 == newStr1));    // false
        
        // equals() сравнивает содержимое - все true
        System.out.println("literal1.equals(literal2): " + literal1.equals(literal2));  // true
        System.out.println("newStr1.equals(newStr2): " + newStr1.equals(newStr2));      // true
        System.out.println("literal1.equals(newStr1): " + literal1.equals(newStr1));    // true
        
        // intern() добавляет строку в Pool
        String newStr3 = new String("Java").intern();
        System.out.println("literal1 == newStr3: " + (literal1 == newStr3));    // true!
    }
}

Метод intern()

Если тебе нужно добавить созданную через new String() строку в String Pool, используй метод intern():

String str = new String("Hello");
String interned = str.intern();  // Теперь находится в Pool

String literal = "Hello";
System.out.println(literal == interned);  // true

Сравнение:

Признак"" Литералnew String()
Место храненияString PoolHeap
Переиспользование✅ Есть❌ Нет
Скорость создания✅ Быстро❌ Медленно
Использование памяти✅ Оптимально❌ Неоптимально
== для одинаковых✅ true❌ false
equals()✅ true✅ true

Практические выводы:

  1. ВСЕГДА используй литеральные строки ("Hello") в обычном коде — это быстрее и экономнее
  2. Избегай new String() — только если есть веская причина
  3. Для сравнения ВСЕГДА используй equals(), никогда не используй == для строк
  4. String Pool находится в PermGen (до Java 8) или Metaspace (Java 8+)
  5. В Java 9+ String Pool работает еще оптимальнее благодаря компактным строкам
В чем разница между написанием строк в "" и вызовом new String? | PrepBro