← Назад к вопросам
В чем разница между написанием строк в "" и вызовом 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 Pool | Heap |
| Переиспользование | ✅ Есть | ❌ Нет |
| Скорость создания | ✅ Быстро | ❌ Медленно |
| Использование памяти | ✅ Оптимально | ❌ Неоптимально |
== для одинаковых | ✅ true | ❌ false |
equals() | ✅ true | ✅ true |
Практические выводы:
- ВСЕГДА используй литеральные строки (
"Hello") в обычном коде — это быстрее и экономнее - Избегай
new String()— только если есть веская причина - Для сравнения ВСЕГДА используй
equals(), никогда не используй==для строк - String Pool находится в PermGen (до Java 8) или Metaspace (Java 8+)
- В Java 9+ String Pool работает еще оптимальнее благодаря компактным строкам